gdscript_compiler.cpp 109 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010
  1. /*************************************************************************/
  2. /* gdscript_compiler.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_compiler.h"
  31. #include "gdscript.h"
  32. #include "gdscript_cache.h"
  33. bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) {
  34. if (codegen.function_node && codegen.function_node->is_static) {
  35. return false;
  36. }
  37. if (codegen.stack_identifiers.has(p_name)) {
  38. return false; //shadowed
  39. }
  40. return _is_class_member_property(codegen.script, p_name);
  41. }
  42. bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringName &p_name) {
  43. GDScript *scr = owner;
  44. GDScriptNativeClass *nc = nullptr;
  45. while (scr) {
  46. if (scr->native.is_valid()) {
  47. nc = scr->native.ptr();
  48. }
  49. scr = scr->_base;
  50. }
  51. ERR_FAIL_COND_V(!nc, false);
  52. return ClassDB::has_property(nc->get_name(), p_name);
  53. }
  54. void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::Node *p_node) {
  55. if (error != "") {
  56. return;
  57. }
  58. error = p_error;
  59. if (p_node) {
  60. err_line = p_node->start_line;
  61. err_column = p_node->leftmost_column;
  62. } else {
  63. err_line = 0;
  64. err_column = 0;
  65. }
  66. }
  67. bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptParser::UnaryOpNode *on, Variant::Operator op, int p_stack_level) {
  68. int src_address_a = _parse_expression(codegen, on->operand, p_stack_level);
  69. if (src_address_a < 0) {
  70. return false;
  71. }
  72. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator
  73. codegen.opcodes.push_back(op); //which operator
  74. codegen.opcodes.push_back(src_address_a); // argument 1
  75. codegen.opcodes.push_back(src_address_a); // argument 2 (repeated)
  76. //codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter)
  77. return true;
  78. }
  79. bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_left_operand, const GDScriptParser::ExpressionNode *p_right_operand, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) {
  80. int src_address_a = _parse_expression(codegen, p_left_operand, p_stack_level, false, p_initializer, p_index_addr);
  81. if (src_address_a < 0) {
  82. return false;
  83. }
  84. if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
  85. p_stack_level++; //uses stack for return, increase stack
  86. }
  87. int src_address_b = _parse_expression(codegen, p_right_operand, p_stack_level, false, p_initializer);
  88. if (src_address_b < 0) {
  89. return false;
  90. }
  91. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator
  92. codegen.opcodes.push_back(op); //which operator
  93. codegen.opcodes.push_back(src_address_a); // argument 1
  94. codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
  95. return true;
  96. }
  97. bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::BinaryOpNode *on, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) {
  98. return _create_binary_operator(codegen, on->left_operand, on->right_operand, op, p_stack_level, p_initializer, p_index_addr);
  99. }
  100. GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::DataType &p_datatype) const {
  101. if (!p_datatype.is_set() || !p_datatype.is_hard_type()) {
  102. return GDScriptDataType();
  103. }
  104. GDScriptDataType result;
  105. result.has_type = true;
  106. switch (p_datatype.kind) {
  107. case GDScriptParser::DataType::VARIANT: {
  108. result.has_type = false;
  109. } break;
  110. case GDScriptParser::DataType::BUILTIN: {
  111. result.kind = GDScriptDataType::BUILTIN;
  112. result.builtin_type = p_datatype.builtin_type;
  113. } break;
  114. case GDScriptParser::DataType::NATIVE: {
  115. result.kind = GDScriptDataType::NATIVE;
  116. result.native_type = p_datatype.native_type;
  117. } break;
  118. case GDScriptParser::DataType::SCRIPT: {
  119. result.kind = GDScriptDataType::SCRIPT;
  120. result.script_type = p_datatype.script_type;
  121. result.native_type = result.script_type->get_instance_base_type();
  122. } break;
  123. case GDScriptParser::DataType::CLASS: {
  124. // Locate class by constructing the path to it and following that path
  125. GDScriptParser::ClassNode *class_type = p_datatype.class_type;
  126. if (class_type) {
  127. if (class_type->fqcn.begins_with(main_script->path) || (!main_script->name.empty() && class_type->fqcn.begins_with(main_script->name))) {
  128. // Local class.
  129. List<StringName> names;
  130. while (class_type->outer) {
  131. names.push_back(class_type->identifier->name);
  132. class_type = class_type->outer;
  133. }
  134. Ref<GDScript> script = Ref<GDScript>(main_script);
  135. while (names.back()) {
  136. if (!script->subclasses.has(names.back()->get())) {
  137. ERR_PRINT("Parser bug: Cannot locate datatype class.");
  138. result.has_type = false;
  139. return GDScriptDataType();
  140. }
  141. script = script->subclasses[names.back()->get()];
  142. names.pop_back();
  143. }
  144. result.kind = GDScriptDataType::GDSCRIPT;
  145. result.script_type = script;
  146. result.native_type = script->get_instance_base_type();
  147. } else {
  148. result.kind = GDScriptDataType::GDSCRIPT;
  149. result.script_type = GDScriptCache::get_shallow_script(p_datatype.script_path, main_script->path);
  150. result.native_type = p_datatype.native_type;
  151. }
  152. }
  153. } break;
  154. case GDScriptParser::DataType::ENUM_VALUE:
  155. result.has_type = true;
  156. result.kind = GDScriptDataType::BUILTIN;
  157. result.builtin_type = Variant::INT;
  158. break;
  159. case GDScriptParser::DataType::ENUM:
  160. result.has_type = true;
  161. result.kind = GDScriptDataType::BUILTIN;
  162. result.builtin_type = Variant::DICTIONARY;
  163. break;
  164. case GDScriptParser::DataType::UNRESOLVED: {
  165. ERR_PRINT("Parser bug: converting unresolved type.");
  166. return GDScriptDataType();
  167. }
  168. }
  169. return result;
  170. }
  171. int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::AssignmentNode *p_assignment, int p_stack_level, int p_index_addr) {
  172. Variant::Operator var_op = Variant::OP_MAX;
  173. switch (p_assignment->operation) {
  174. case GDScriptParser::AssignmentNode::OP_ADDITION:
  175. var_op = Variant::OP_ADD;
  176. break;
  177. case GDScriptParser::AssignmentNode::OP_SUBTRACTION:
  178. var_op = Variant::OP_SUBTRACT;
  179. break;
  180. case GDScriptParser::AssignmentNode::OP_MULTIPLICATION:
  181. var_op = Variant::OP_MULTIPLY;
  182. break;
  183. case GDScriptParser::AssignmentNode::OP_DIVISION:
  184. var_op = Variant::OP_DIVIDE;
  185. break;
  186. case GDScriptParser::AssignmentNode::OP_MODULO:
  187. var_op = Variant::OP_MODULE;
  188. break;
  189. case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_LEFT:
  190. var_op = Variant::OP_SHIFT_LEFT;
  191. break;
  192. case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_RIGHT:
  193. var_op = Variant::OP_SHIFT_RIGHT;
  194. break;
  195. case GDScriptParser::AssignmentNode::OP_BIT_AND:
  196. var_op = Variant::OP_BIT_AND;
  197. break;
  198. case GDScriptParser::AssignmentNode::OP_BIT_OR:
  199. var_op = Variant::OP_BIT_OR;
  200. break;
  201. case GDScriptParser::AssignmentNode::OP_BIT_XOR:
  202. var_op = Variant::OP_BIT_XOR;
  203. break;
  204. case GDScriptParser::AssignmentNode::OP_NONE: {
  205. //none
  206. } break;
  207. default: {
  208. ERR_FAIL_V(-1);
  209. }
  210. }
  211. // bool initializer = p_expression->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN;
  212. if (var_op == Variant::OP_MAX) {
  213. return _parse_expression(codegen, p_assignment->assigned_value, p_stack_level, false, false);
  214. }
  215. if (!_create_binary_operator(codegen, p_assignment->assignee, p_assignment->assigned_value, var_op, p_stack_level, false, p_index_addr)) {
  216. return -1;
  217. }
  218. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  219. codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
  220. codegen.alloc_stack(p_stack_level);
  221. return dst_addr;
  222. }
  223. bool GDScriptCompiler::_generate_typed_assign(CodeGen &codegen, int p_src_address, int p_dst_address, const GDScriptDataType &p_datatype, const GDScriptParser::DataType &p_value_type) {
  224. if (p_datatype.has_type && p_value_type.is_variant()) {
  225. // Typed assignment
  226. switch (p_datatype.kind) {
  227. case GDScriptDataType::BUILTIN: {
  228. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); // perform operator
  229. codegen.opcodes.push_back(p_datatype.builtin_type); // variable type
  230. codegen.opcodes.push_back(p_dst_address); // argument 1
  231. codegen.opcodes.push_back(p_src_address); // argument 2
  232. } break;
  233. case GDScriptDataType::NATIVE: {
  234. int class_idx;
  235. if (GDScriptLanguage::get_singleton()->get_global_map().has(p_datatype.native_type)) {
  236. class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_datatype.native_type];
  237. class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
  238. } else {
  239. // _set_error("Invalid native class type '" + String(p_datatype.native_type) + "'.", on->arguments[0]);
  240. return false;
  241. }
  242. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE); // perform operator
  243. codegen.opcodes.push_back(class_idx); // variable type
  244. codegen.opcodes.push_back(p_dst_address); // argument 1
  245. codegen.opcodes.push_back(p_src_address); // argument 2
  246. } break;
  247. case GDScriptDataType::SCRIPT:
  248. case GDScriptDataType::GDSCRIPT: {
  249. Variant script = p_datatype.script_type;
  250. int idx = codegen.get_constant_pos(script); //make it a local constant (faster access)
  251. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT); // perform operator
  252. codegen.opcodes.push_back(idx); // variable type
  253. codegen.opcodes.push_back(p_dst_address); // argument 1
  254. codegen.opcodes.push_back(p_src_address); // argument 2
  255. } break;
  256. default: {
  257. ERR_PRINT("Compiler bug: unresolved assign.");
  258. // Shouldn't get here, but fail-safe to a regular assignment
  259. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
  260. codegen.opcodes.push_back(p_dst_address); // argument 1
  261. codegen.opcodes.push_back(p_src_address); // argument 2 (unary only takes one parameter)
  262. }
  263. }
  264. } else {
  265. if (p_datatype.kind == GDScriptDataType::BUILTIN && p_value_type.kind == GDScriptParser::DataType::BUILTIN && p_datatype.builtin_type != p_value_type.builtin_type) {
  266. // Need conversion.
  267. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); // perform operator
  268. codegen.opcodes.push_back(p_datatype.builtin_type); // variable type
  269. codegen.opcodes.push_back(p_dst_address); // argument 1
  270. codegen.opcodes.push_back(p_src_address); // argument 2
  271. } else {
  272. // Either untyped assignment or already type-checked by the parser
  273. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
  274. codegen.opcodes.push_back(p_dst_address); // argument 1
  275. codegen.opcodes.push_back(p_src_address); // argument 2 (unary only takes one parameter)
  276. }
  277. }
  278. return true;
  279. }
  280. int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_expression, int p_stack_level, bool p_root, bool p_initializer, int p_index_addr) {
  281. if (p_expression->is_constant) {
  282. return codegen.get_constant_pos(p_expression->reduced_value);
  283. }
  284. switch (p_expression->type) {
  285. //should parse variable declaration and adjust stack accordingly...
  286. case GDScriptParser::Node::IDENTIFIER: {
  287. //return identifier
  288. //wait, identifier could be a local variable or something else... careful here, must reference properly
  289. //as stack may be more interesting to work with
  290. //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases performance a lot.
  291. const GDScriptParser::IdentifierNode *in = static_cast<const GDScriptParser::IdentifierNode *>(p_expression);
  292. StringName identifier = in->name;
  293. // TRY STACK!
  294. if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
  295. int pos = codegen.stack_identifiers[identifier];
  296. return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
  297. }
  298. // TRY LOCAL CONSTANTS!
  299. if (codegen.local_named_constants.has(identifier)) {
  300. return codegen.local_named_constants[identifier] | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
  301. }
  302. // TRY CLASS MEMBER
  303. if (_is_class_member_property(codegen, identifier)) {
  304. //get property
  305. codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET_MEMBER); // perform operator
  306. codegen.opcodes.push_back(codegen.get_name_map_pos(identifier)); // argument 2 (unary only takes one parameter)
  307. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  308. codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
  309. codegen.alloc_stack(p_stack_level);
  310. return dst_addr;
  311. }
  312. //TRY MEMBERS!
  313. if (!codegen.function_node || !codegen.function_node->is_static) {
  314. // TRY MEMBER VARIABLES!
  315. //static function
  316. if (codegen.script->member_indices.has(identifier)) {
  317. if (codegen.script->member_indices[identifier].getter != StringName() && codegen.script->member_indices[identifier].getter != codegen.function_name) {
  318. // Perform getter.
  319. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_RETURN);
  320. codegen.opcodes.push_back(0); // Argument count.
  321. codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // Base (self).
  322. codegen.opcodes.push_back(codegen.get_name_map_pos(codegen.script->member_indices[identifier].getter)); // Method name.
  323. // Destination.
  324. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  325. codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
  326. codegen.alloc_stack(p_stack_level);
  327. return dst_addr;
  328. } else {
  329. // No getter or inside getter: direct member access.
  330. int idx = codegen.script->member_indices[identifier].index;
  331. return idx | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS); //argument (stack root)
  332. }
  333. }
  334. }
  335. //TRY CLASS CONSTANTS
  336. GDScript *owner = codegen.script;
  337. while (owner) {
  338. GDScript *scr = owner;
  339. GDScriptNativeClass *nc = nullptr;
  340. while (scr) {
  341. if (scr->constants.has(identifier)) {
  342. //int idx=scr->constants[identifier];
  343. int idx = codegen.get_name_map_pos(identifier);
  344. return idx | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root)
  345. }
  346. if (scr->native.is_valid()) {
  347. nc = scr->native.ptr();
  348. }
  349. scr = scr->_base;
  350. }
  351. // CLASS C++ Integer Constant
  352. if (nc) {
  353. bool success = false;
  354. int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success);
  355. if (success) {
  356. Variant key = constant;
  357. int idx;
  358. if (!codegen.constant_map.has(key)) {
  359. idx = codegen.constant_map.size();
  360. codegen.constant_map[key] = idx;
  361. } else {
  362. idx = codegen.constant_map[key];
  363. }
  364. return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //make it a local constant (faster access)
  365. }
  366. }
  367. owner = owner->_owner;
  368. }
  369. // TRY SIGNALS AND METHODS (can be made callables)
  370. if (codegen.class_node->members_indices.has(identifier)) {
  371. const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]];
  372. if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) {
  373. // Get like it was a property.
  374. codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET_NAMED); // perform operator
  375. codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // Self.
  376. codegen.opcodes.push_back(codegen.get_name_map_pos(identifier)); // argument 2 (unary only takes one parameter)
  377. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  378. codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
  379. codegen.alloc_stack(p_stack_level);
  380. return dst_addr;
  381. }
  382. }
  383. if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
  384. int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier];
  385. return idx | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
  386. }
  387. /* TRY GLOBAL CLASSES */
  388. if (ScriptServer::is_global_class(identifier)) {
  389. const GDScriptParser::ClassNode *class_node = codegen.class_node;
  390. while (class_node->outer) {
  391. class_node = class_node->outer;
  392. }
  393. RES res;
  394. if (class_node->identifier && class_node->identifier->name == identifier) {
  395. res = Ref<GDScript>(main_script);
  396. } else {
  397. res = ResourceLoader::load(ScriptServer::get_global_class_path(identifier));
  398. if (res.is_null()) {
  399. _set_error("Can't load global class " + String(identifier) + ", cyclic reference?", p_expression);
  400. return -1;
  401. }
  402. }
  403. Variant key = res;
  404. int idx;
  405. if (!codegen.constant_map.has(key)) {
  406. idx = codegen.constant_map.size();
  407. codegen.constant_map[key] = idx;
  408. } else {
  409. idx = codegen.constant_map[key];
  410. }
  411. return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //make it a local constant (faster access)
  412. }
  413. #ifdef TOOLS_ENABLED
  414. if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
  415. int idx = codegen.named_globals.find(identifier);
  416. if (idx == -1) {
  417. idx = codegen.named_globals.size();
  418. codegen.named_globals.push_back(identifier);
  419. }
  420. return idx | (GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL << GDScriptFunction::ADDR_BITS);
  421. }
  422. #endif
  423. //not found, error
  424. _set_error("Identifier not found: " + String(identifier), p_expression);
  425. return -1;
  426. } break;
  427. case GDScriptParser::Node::LITERAL: {
  428. //return constant
  429. const GDScriptParser::LiteralNode *cn = static_cast<const GDScriptParser::LiteralNode *>(p_expression);
  430. int idx;
  431. if (!codegen.constant_map.has(cn->value)) {
  432. idx = codegen.constant_map.size();
  433. codegen.constant_map[cn->value] = idx;
  434. } else {
  435. idx = codegen.constant_map[cn->value];
  436. }
  437. return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root)
  438. } break;
  439. case GDScriptParser::Node::SELF: {
  440. //return constant
  441. if (codegen.function_node && codegen.function_node->is_static) {
  442. _set_error("'self' not present in static function!", p_expression);
  443. return -1;
  444. }
  445. return (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
  446. } break;
  447. case GDScriptParser::Node::ARRAY: {
  448. const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(p_expression);
  449. Vector<int> values;
  450. int slevel = p_stack_level;
  451. for (int i = 0; i < an->elements.size(); i++) {
  452. int ret = _parse_expression(codegen, an->elements[i], slevel);
  453. if (ret < 0) {
  454. return ret;
  455. }
  456. if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  457. slevel++;
  458. codegen.alloc_stack(slevel);
  459. }
  460. values.push_back(ret);
  461. }
  462. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_ARRAY);
  463. codegen.opcodes.push_back(values.size());
  464. for (int i = 0; i < values.size(); i++) {
  465. codegen.opcodes.push_back(values[i]);
  466. }
  467. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  468. codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
  469. codegen.alloc_stack(p_stack_level);
  470. return dst_addr;
  471. } break;
  472. case GDScriptParser::Node::DICTIONARY: {
  473. const GDScriptParser::DictionaryNode *dn = static_cast<const GDScriptParser::DictionaryNode *>(p_expression);
  474. Vector<int> elements;
  475. int slevel = p_stack_level;
  476. for (int i = 0; i < dn->elements.size(); i++) {
  477. // Key.
  478. int ret = -1;
  479. switch (dn->style) {
  480. case GDScriptParser::DictionaryNode::PYTHON_DICT:
  481. // Python-style: key is any expression.
  482. ret = _parse_expression(codegen, dn->elements[i].key, slevel);
  483. if (ret < 0) {
  484. return ret;
  485. }
  486. if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  487. slevel++;
  488. codegen.alloc_stack(slevel);
  489. }
  490. break;
  491. case GDScriptParser::DictionaryNode::LUA_TABLE:
  492. // Lua-style: key is an identifier interpreted as string.
  493. String key = static_cast<const GDScriptParser::IdentifierNode *>(dn->elements[i].key)->name;
  494. ret = codegen.get_constant_pos(key);
  495. break;
  496. }
  497. elements.push_back(ret);
  498. ret = _parse_expression(codegen, dn->elements[i].value, slevel);
  499. if (ret < 0) {
  500. return ret;
  501. }
  502. if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  503. slevel++;
  504. codegen.alloc_stack(slevel);
  505. }
  506. elements.push_back(ret);
  507. }
  508. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY);
  509. codegen.opcodes.push_back(dn->elements.size());
  510. for (int i = 0; i < elements.size(); i++) {
  511. codegen.opcodes.push_back(elements[i]);
  512. }
  513. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  514. codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
  515. codegen.alloc_stack(p_stack_level);
  516. return dst_addr;
  517. } break;
  518. case GDScriptParser::Node::CAST: {
  519. const GDScriptParser::CastNode *cn = static_cast<const GDScriptParser::CastNode *>(p_expression);
  520. int slevel = p_stack_level;
  521. int src_addr = _parse_expression(codegen, cn->operand, slevel);
  522. if (src_addr < 0) {
  523. return src_addr;
  524. }
  525. if (src_addr & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
  526. slevel++;
  527. codegen.alloc_stack(slevel);
  528. }
  529. GDScriptDataType cast_type = _gdtype_from_datatype(cn->cast_type->get_datatype());
  530. switch (cast_type.kind) {
  531. case GDScriptDataType::BUILTIN: {
  532. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_BUILTIN);
  533. codegen.opcodes.push_back(cast_type.builtin_type);
  534. } break;
  535. case GDScriptDataType::NATIVE: {
  536. int class_idx;
  537. if (GDScriptLanguage::get_singleton()->get_global_map().has(cast_type.native_type)) {
  538. class_idx = GDScriptLanguage::get_singleton()->get_global_map()[cast_type.native_type];
  539. class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
  540. } else {
  541. _set_error("Invalid native class type '" + String(cast_type.native_type) + "'.", cn);
  542. return -1;
  543. }
  544. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_NATIVE); // perform operator
  545. codegen.opcodes.push_back(class_idx); // variable type
  546. } break;
  547. case GDScriptDataType::SCRIPT:
  548. case GDScriptDataType::GDSCRIPT: {
  549. Variant script = cast_type.script_type;
  550. int idx = codegen.get_constant_pos(script); //make it a local constant (faster access)
  551. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_SCRIPT); // perform operator
  552. codegen.opcodes.push_back(idx); // variable type
  553. } break;
  554. default: {
  555. _set_error("Parser bug: unresolved data type.", cn);
  556. return -1;
  557. }
  558. }
  559. codegen.opcodes.push_back(src_addr); // source address
  560. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  561. codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
  562. codegen.alloc_stack(p_stack_level);
  563. return dst_addr;
  564. } break;
  565. //hell breaks loose
  566. #define OPERATOR_RETURN \
  567. int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); \
  568. codegen.opcodes.push_back(dst_addr); \
  569. codegen.alloc_stack(p_stack_level); \
  570. return dst_addr
  571. case GDScriptParser::Node::CALL: {
  572. const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression);
  573. if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name) != Variant::VARIANT_MAX) {
  574. //construct a basic type
  575. Variant::Type vtype = GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
  576. Vector<int> arguments;
  577. int slevel = p_stack_level;
  578. for (int i = 0; i < call->arguments.size(); i++) {
  579. int ret = _parse_expression(codegen, call->arguments[i], slevel);
  580. if (ret < 0) {
  581. return ret;
  582. }
  583. if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  584. slevel++;
  585. codegen.alloc_stack(slevel);
  586. }
  587. arguments.push_back(ret);
  588. }
  589. //push call bytecode
  590. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT); // basic type constructor
  591. codegen.opcodes.push_back(vtype); //instance
  592. codegen.opcodes.push_back(arguments.size()); //argument count
  593. codegen.alloc_call(arguments.size());
  594. for (int i = 0; i < arguments.size(); i++) {
  595. codegen.opcodes.push_back(arguments[i]); //arguments
  596. }
  597. } else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_function(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name) != GDScriptFunctions::FUNC_MAX) {
  598. //built in function
  599. Vector<int> arguments;
  600. int slevel = p_stack_level;
  601. for (int i = 0; i < call->arguments.size(); i++) {
  602. int ret = _parse_expression(codegen, call->arguments[i], slevel);
  603. if (ret < 0) {
  604. return ret;
  605. }
  606. if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  607. slevel++;
  608. codegen.alloc_stack(slevel);
  609. }
  610. arguments.push_back(ret);
  611. }
  612. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
  613. codegen.opcodes.push_back(GDScriptParser::get_builtin_function(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name));
  614. codegen.opcodes.push_back(arguments.size());
  615. codegen.alloc_call(arguments.size());
  616. for (int i = 0; i < arguments.size(); i++) {
  617. codegen.opcodes.push_back(arguments[i]);
  618. }
  619. } else {
  620. //regular function
  621. const GDScriptParser::ExpressionNode *callee = call->callee;
  622. Vector<int> arguments;
  623. int slevel = p_stack_level;
  624. // TODO: Use callables when possible if needed.
  625. int ret = -1;
  626. int super_address = -1;
  627. if (call->is_super) {
  628. // Super call.
  629. if (call->callee == nullptr) {
  630. // Implicit super function call.
  631. super_address = codegen.get_name_map_pos(codegen.function_node->identifier->name);
  632. } else {
  633. super_address = codegen.get_name_map_pos(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
  634. }
  635. } else {
  636. if (callee->type == GDScriptParser::Node::IDENTIFIER) {
  637. // Self function call.
  638. if (codegen.function_node && codegen.function_node->is_static) {
  639. ret = (GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS);
  640. } else {
  641. ret = (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
  642. }
  643. arguments.push_back(ret);
  644. ret = codegen.get_name_map_pos(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
  645. arguments.push_back(ret);
  646. } else if (callee->type == GDScriptParser::Node::SUBSCRIPT) {
  647. const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(call->callee);
  648. if (subscript->is_attribute) {
  649. ret = _parse_expression(codegen, subscript->base, slevel);
  650. if (ret < 0) {
  651. return ret;
  652. }
  653. if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  654. slevel++;
  655. codegen.alloc_stack(slevel);
  656. }
  657. arguments.push_back(ret);
  658. arguments.push_back(codegen.get_name_map_pos(subscript->attribute->name));
  659. } else {
  660. _set_error("Cannot call something that isn't a function.", call->callee);
  661. return -1;
  662. }
  663. } else {
  664. _set_error("Cannot call something that isn't a function.", call->callee);
  665. return -1;
  666. }
  667. }
  668. for (int i = 0; i < call->arguments.size(); i++) {
  669. ret = _parse_expression(codegen, call->arguments[i], slevel);
  670. if (ret < 0) {
  671. return ret;
  672. }
  673. if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  674. slevel++;
  675. codegen.alloc_stack(slevel);
  676. }
  677. arguments.push_back(ret);
  678. }
  679. int opcode = GDScriptFunction::OPCODE_CALL_RETURN;
  680. if (call->is_super) {
  681. opcode = GDScriptFunction::OPCODE_CALL_SELF_BASE;
  682. } else if (within_await) {
  683. opcode = GDScriptFunction::OPCODE_CALL_ASYNC;
  684. } else if (p_root) {
  685. opcode = GDScriptFunction::OPCODE_CALL;
  686. }
  687. codegen.opcodes.push_back(opcode); // perform operator
  688. if (call->is_super) {
  689. codegen.opcodes.push_back(super_address);
  690. }
  691. codegen.opcodes.push_back(call->arguments.size());
  692. codegen.alloc_call(call->arguments.size());
  693. for (int i = 0; i < arguments.size(); i++) {
  694. codegen.opcodes.push_back(arguments[i]);
  695. }
  696. }
  697. OPERATOR_RETURN;
  698. } break;
  699. case GDScriptParser::Node::GET_NODE: {
  700. const GDScriptParser::GetNodeNode *get_node = static_cast<const GDScriptParser::GetNodeNode *>(p_expression);
  701. String node_name;
  702. if (get_node->string != nullptr) {
  703. node_name += String(get_node->string->value);
  704. } else {
  705. for (int i = 0; i < get_node->chain.size(); i++) {
  706. if (i > 0) {
  707. node_name += "/";
  708. }
  709. node_name += get_node->chain[i]->name;
  710. }
  711. }
  712. int arg_address = codegen.get_constant_pos(NodePath(node_name));
  713. codegen.opcodes.push_back(p_root ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN);
  714. codegen.opcodes.push_back(1); // number of arguments.
  715. codegen.alloc_call(1);
  716. codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // self.
  717. codegen.opcodes.push_back(codegen.get_name_map_pos("get_node")); // function.
  718. codegen.opcodes.push_back(arg_address); // argument (NodePath).
  719. OPERATOR_RETURN;
  720. } break;
  721. case GDScriptParser::Node::PRELOAD: {
  722. const GDScriptParser::PreloadNode *preload = static_cast<const GDScriptParser::PreloadNode *>(p_expression);
  723. // Add resource as constant.
  724. return codegen.get_constant_pos(preload->resource);
  725. } break;
  726. case GDScriptParser::Node::AWAIT: {
  727. const GDScriptParser::AwaitNode *await = static_cast<const GDScriptParser::AwaitNode *>(p_expression);
  728. int slevel = p_stack_level;
  729. within_await = true;
  730. int argument = _parse_expression(codegen, await->to_await, slevel);
  731. within_await = false;
  732. if (argument < 0) {
  733. return argument;
  734. }
  735. if ((argument >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  736. slevel++;
  737. codegen.alloc_stack(slevel);
  738. }
  739. //push call bytecode
  740. codegen.opcodes.push_back(GDScriptFunction::OPCODE_AWAIT);
  741. codegen.opcodes.push_back(argument);
  742. codegen.opcodes.push_back(GDScriptFunction::OPCODE_AWAIT_RESUME);
  743. //next will be where to place the result :)
  744. OPERATOR_RETURN;
  745. } break;
  746. //indexing operator
  747. case GDScriptParser::Node::SUBSCRIPT: {
  748. int slevel = p_stack_level;
  749. const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(p_expression);
  750. int from = _parse_expression(codegen, subscript->base, slevel);
  751. if (from < 0) {
  752. return from;
  753. }
  754. bool named = subscript->is_attribute;
  755. int index;
  756. if (p_index_addr != 0) {
  757. index = p_index_addr;
  758. } else if (subscript->is_attribute) {
  759. if (subscript->base->type == GDScriptParser::Node::SELF && codegen.script) {
  760. GDScriptParser::IdentifierNode *identifier = subscript->attribute;
  761. const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(identifier->name);
  762. #ifdef DEBUG_ENABLED
  763. if (MI && MI->get().getter == codegen.function_name) {
  764. String n = identifier->name;
  765. _set_error("Must use '" + n + "' instead of 'self." + n + "' in getter.", identifier);
  766. return -1;
  767. }
  768. #endif
  769. if (MI && MI->get().getter == "") {
  770. // Faster than indexing self (as if no self. had been used)
  771. return (MI->get().index) | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS);
  772. }
  773. }
  774. index = codegen.get_name_map_pos(subscript->attribute->name);
  775. } else {
  776. if (subscript->index->type == GDScriptParser::Node::LITERAL && static_cast<const GDScriptParser::LiteralNode *>(subscript->index)->value.get_type() == Variant::STRING) {
  777. //also, somehow, named (speed up anyway)
  778. StringName name = static_cast<const GDScriptParser::LiteralNode *>(subscript->index)->value;
  779. index = codegen.get_name_map_pos(name);
  780. named = true;
  781. } else {
  782. //regular indexing
  783. if (from & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
  784. slevel++;
  785. codegen.alloc_stack(slevel);
  786. }
  787. index = _parse_expression(codegen, subscript->index, slevel);
  788. if (index < 0) {
  789. return index;
  790. }
  791. }
  792. }
  793. codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET); // perform operator
  794. codegen.opcodes.push_back(from); // argument 1
  795. codegen.opcodes.push_back(index); // argument 2 (unary only takes one parameter)
  796. OPERATOR_RETURN;
  797. } break;
  798. case GDScriptParser::Node::UNARY_OPERATOR: {
  799. //unary operators
  800. const GDScriptParser::UnaryOpNode *unary = static_cast<const GDScriptParser::UnaryOpNode *>(p_expression);
  801. switch (unary->operation) {
  802. case GDScriptParser::UnaryOpNode::OP_NEGATIVE: {
  803. if (!_create_unary_operator(codegen, unary, Variant::OP_NEGATE, p_stack_level)) {
  804. return -1;
  805. }
  806. } break;
  807. case GDScriptParser::UnaryOpNode::OP_POSITIVE: {
  808. if (!_create_unary_operator(codegen, unary, Variant::OP_POSITIVE, p_stack_level)) {
  809. return -1;
  810. }
  811. } break;
  812. case GDScriptParser::UnaryOpNode::OP_LOGIC_NOT: {
  813. if (!_create_unary_operator(codegen, unary, Variant::OP_NOT, p_stack_level)) {
  814. return -1;
  815. }
  816. } break;
  817. case GDScriptParser::UnaryOpNode::OP_COMPLEMENT: {
  818. if (!_create_unary_operator(codegen, unary, Variant::OP_BIT_NEGATE, p_stack_level)) {
  819. return -1;
  820. }
  821. } break;
  822. }
  823. OPERATOR_RETURN;
  824. }
  825. case GDScriptParser::Node::BINARY_OPERATOR: {
  826. //binary operators (in precedence order)
  827. const GDScriptParser::BinaryOpNode *binary = static_cast<const GDScriptParser::BinaryOpNode *>(p_expression);
  828. switch (binary->operation) {
  829. case GDScriptParser::BinaryOpNode::OP_LOGIC_AND: {
  830. // AND operator with early out on failure
  831. int res = _parse_expression(codegen, binary->left_operand, p_stack_level);
  832. if (res < 0) {
  833. return res;
  834. }
  835. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  836. codegen.opcodes.push_back(res);
  837. int jump_fail_pos = codegen.opcodes.size();
  838. codegen.opcodes.push_back(0);
  839. res = _parse_expression(codegen, binary->right_operand, p_stack_level);
  840. if (res < 0) {
  841. return res;
  842. }
  843. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  844. codegen.opcodes.push_back(res);
  845. int jump_fail_pos2 = codegen.opcodes.size();
  846. codegen.opcodes.push_back(0);
  847. codegen.alloc_stack(p_stack_level); //it will be used..
  848. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TRUE);
  849. codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  850. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  851. codegen.opcodes.push_back(codegen.opcodes.size() + 3);
  852. codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size();
  853. codegen.opcodes.write[jump_fail_pos2] = codegen.opcodes.size();
  854. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_FALSE);
  855. codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  856. return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  857. } break;
  858. case GDScriptParser::BinaryOpNode::OP_LOGIC_OR: {
  859. // OR operator with early out on success
  860. int res = _parse_expression(codegen, binary->left_operand, p_stack_level);
  861. if (res < 0) {
  862. return res;
  863. }
  864. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF);
  865. codegen.opcodes.push_back(res);
  866. int jump_success_pos = codegen.opcodes.size();
  867. codegen.opcodes.push_back(0);
  868. res = _parse_expression(codegen, binary->right_operand, p_stack_level);
  869. if (res < 0) {
  870. return res;
  871. }
  872. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF);
  873. codegen.opcodes.push_back(res);
  874. int jump_success_pos2 = codegen.opcodes.size();
  875. codegen.opcodes.push_back(0);
  876. codegen.alloc_stack(p_stack_level); //it will be used..
  877. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_FALSE);
  878. codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  879. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  880. codegen.opcodes.push_back(codegen.opcodes.size() + 3);
  881. codegen.opcodes.write[jump_success_pos] = codegen.opcodes.size();
  882. codegen.opcodes.write[jump_success_pos2] = codegen.opcodes.size();
  883. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TRUE);
  884. codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  885. return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  886. } break;
  887. case GDScriptParser::BinaryOpNode::OP_TYPE_TEST: {
  888. int slevel = p_stack_level;
  889. int src_address_a = _parse_expression(codegen, binary->left_operand, slevel);
  890. if (src_address_a < 0) {
  891. return -1;
  892. }
  893. if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
  894. slevel++; //uses stack for return, increase stack
  895. }
  896. int src_address_b = -1;
  897. bool builtin = false;
  898. if (binary->right_operand->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<const GDScriptParser::IdentifierNode *>(binary->right_operand)->name) != Variant::VARIANT_MAX) {
  899. // `is` with builtin type
  900. builtin = true;
  901. src_address_b = (int)GDScriptParser::get_builtin_type(static_cast<const GDScriptParser::IdentifierNode *>(binary->right_operand)->name);
  902. } else {
  903. src_address_b = _parse_expression(codegen, binary->right_operand, slevel);
  904. if (src_address_b < 0) {
  905. return -1;
  906. }
  907. }
  908. codegen.opcodes.push_back(builtin ? GDScriptFunction::OPCODE_IS_BUILTIN : GDScriptFunction::OPCODE_EXTENDS_TEST); // perform operator
  909. codegen.opcodes.push_back(src_address_a); // argument 1
  910. codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
  911. } break;
  912. case GDScriptParser::BinaryOpNode::OP_CONTENT_TEST: {
  913. if (!_create_binary_operator(codegen, binary, Variant::OP_IN, p_stack_level)) {
  914. return -1;
  915. }
  916. } break;
  917. case GDScriptParser::BinaryOpNode::OP_COMP_EQUAL: {
  918. if (!_create_binary_operator(codegen, binary, Variant::OP_EQUAL, p_stack_level)) {
  919. return -1;
  920. }
  921. } break;
  922. case GDScriptParser::BinaryOpNode::OP_COMP_NOT_EQUAL: {
  923. if (!_create_binary_operator(codegen, binary, Variant::OP_NOT_EQUAL, p_stack_level)) {
  924. return -1;
  925. }
  926. } break;
  927. case GDScriptParser::BinaryOpNode::OP_COMP_LESS: {
  928. if (!_create_binary_operator(codegen, binary, Variant::OP_LESS, p_stack_level)) {
  929. return -1;
  930. }
  931. } break;
  932. case GDScriptParser::BinaryOpNode::OP_COMP_LESS_EQUAL: {
  933. if (!_create_binary_operator(codegen, binary, Variant::OP_LESS_EQUAL, p_stack_level)) {
  934. return -1;
  935. }
  936. } break;
  937. case GDScriptParser::BinaryOpNode::OP_COMP_GREATER: {
  938. if (!_create_binary_operator(codegen, binary, Variant::OP_GREATER, p_stack_level)) {
  939. return -1;
  940. }
  941. } break;
  942. case GDScriptParser::BinaryOpNode::OP_COMP_GREATER_EQUAL: {
  943. if (!_create_binary_operator(codegen, binary, Variant::OP_GREATER_EQUAL, p_stack_level)) {
  944. return -1;
  945. }
  946. } break;
  947. case GDScriptParser::BinaryOpNode::OP_ADDITION: {
  948. if (!_create_binary_operator(codegen, binary, Variant::OP_ADD, p_stack_level)) {
  949. return -1;
  950. }
  951. } break;
  952. case GDScriptParser::BinaryOpNode::OP_SUBTRACTION: {
  953. if (!_create_binary_operator(codegen, binary, Variant::OP_SUBTRACT, p_stack_level)) {
  954. return -1;
  955. }
  956. } break;
  957. case GDScriptParser::BinaryOpNode::OP_MULTIPLICATION: {
  958. if (!_create_binary_operator(codegen, binary, Variant::OP_MULTIPLY, p_stack_level)) {
  959. return -1;
  960. }
  961. } break;
  962. case GDScriptParser::BinaryOpNode::OP_DIVISION: {
  963. if (!_create_binary_operator(codegen, binary, Variant::OP_DIVIDE, p_stack_level)) {
  964. return -1;
  965. }
  966. } break;
  967. case GDScriptParser::BinaryOpNode::OP_MODULO: {
  968. if (!_create_binary_operator(codegen, binary, Variant::OP_MODULE, p_stack_level)) {
  969. return -1;
  970. }
  971. } break;
  972. case GDScriptParser::BinaryOpNode::OP_BIT_AND: {
  973. if (!_create_binary_operator(codegen, binary, Variant::OP_BIT_AND, p_stack_level)) {
  974. return -1;
  975. }
  976. } break;
  977. case GDScriptParser::BinaryOpNode::OP_BIT_OR: {
  978. if (!_create_binary_operator(codegen, binary, Variant::OP_BIT_OR, p_stack_level)) {
  979. return -1;
  980. }
  981. } break;
  982. case GDScriptParser::BinaryOpNode::OP_BIT_XOR: {
  983. if (!_create_binary_operator(codegen, binary, Variant::OP_BIT_XOR, p_stack_level)) {
  984. return -1;
  985. }
  986. } break;
  987. //shift
  988. case GDScriptParser::BinaryOpNode::OP_BIT_LEFT_SHIFT: {
  989. if (!_create_binary_operator(codegen, binary, Variant::OP_SHIFT_LEFT, p_stack_level)) {
  990. return -1;
  991. }
  992. } break;
  993. case GDScriptParser::BinaryOpNode::OP_BIT_RIGHT_SHIFT: {
  994. if (!_create_binary_operator(codegen, binary, Variant::OP_SHIFT_RIGHT, p_stack_level)) {
  995. return -1;
  996. }
  997. } break;
  998. }
  999. OPERATOR_RETURN;
  1000. } break;
  1001. // ternary operators
  1002. case GDScriptParser::Node::TERNARY_OPERATOR: {
  1003. // x IF a ELSE y operator with early out on failure
  1004. const GDScriptParser::TernaryOpNode *ternary = static_cast<const GDScriptParser::TernaryOpNode *>(p_expression);
  1005. int res = _parse_expression(codegen, ternary->condition, p_stack_level);
  1006. if (res < 0) {
  1007. return res;
  1008. }
  1009. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1010. codegen.opcodes.push_back(res);
  1011. int jump_fail_pos = codegen.opcodes.size();
  1012. codegen.opcodes.push_back(0);
  1013. res = _parse_expression(codegen, ternary->true_expr, p_stack_level);
  1014. if (res < 0) {
  1015. return res;
  1016. }
  1017. codegen.alloc_stack(p_stack_level); //it will be used..
  1018. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
  1019. codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  1020. codegen.opcodes.push_back(res);
  1021. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1022. int jump_past_pos = codegen.opcodes.size();
  1023. codegen.opcodes.push_back(0);
  1024. codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size();
  1025. res = _parse_expression(codegen, ternary->false_expr, p_stack_level);
  1026. if (res < 0) {
  1027. return res;
  1028. }
  1029. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
  1030. codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  1031. codegen.opcodes.push_back(res);
  1032. codegen.opcodes.write[jump_past_pos] = codegen.opcodes.size();
  1033. return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1034. } break;
  1035. //assignment operators
  1036. case GDScriptParser::Node::ASSIGNMENT: {
  1037. const GDScriptParser::AssignmentNode *assignment = static_cast<const GDScriptParser::AssignmentNode *>(p_expression);
  1038. if (assignment->assignee->type == GDScriptParser::Node::SUBSCRIPT) {
  1039. // SET (chained) MODE!
  1040. const GDScriptParser::SubscriptNode *subscript = static_cast<GDScriptParser::SubscriptNode *>(assignment->assignee);
  1041. #ifdef DEBUG_ENABLED
  1042. if (subscript->is_attribute) {
  1043. if (subscript->base->type == GDScriptParser::Node::SELF && codegen.script) {
  1044. const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(subscript->attribute->name);
  1045. if (MI && MI->get().setter == codegen.function_name) {
  1046. String n = subscript->attribute->name;
  1047. _set_error("Must use '" + n + "' instead of 'self." + n + "' in setter.", subscript);
  1048. return -1;
  1049. }
  1050. }
  1051. }
  1052. #endif
  1053. int slevel = p_stack_level;
  1054. /* Find chain of sets */
  1055. StringName assign_property;
  1056. List<const GDScriptParser::SubscriptNode *> chain;
  1057. {
  1058. //create get/set chain
  1059. const GDScriptParser::SubscriptNode *n = subscript;
  1060. while (true) {
  1061. chain.push_back(n);
  1062. if (n->base->type != GDScriptParser::Node::SUBSCRIPT) {
  1063. //check for a built-in property
  1064. if (n->base->type == GDScriptParser::Node::IDENTIFIER) {
  1065. GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(n->base);
  1066. if (_is_class_member_property(codegen, identifier->name)) {
  1067. assign_property = identifier->name;
  1068. }
  1069. }
  1070. break;
  1071. }
  1072. n = static_cast<const GDScriptParser::SubscriptNode *>(n->base);
  1073. }
  1074. }
  1075. /* Chain of gets */
  1076. //get at (potential) root stack pos, so it can be returned
  1077. int prev_pos = _parse_expression(codegen, chain.back()->get()->base, slevel);
  1078. if (prev_pos < 0) {
  1079. return prev_pos;
  1080. }
  1081. int retval = prev_pos;
  1082. if (retval & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
  1083. slevel++;
  1084. codegen.alloc_stack(slevel);
  1085. }
  1086. Vector<int> setchain;
  1087. if (assign_property != StringName()) {
  1088. // recover and assign at the end, this allows stuff like
  1089. // position.x+=2.0
  1090. // in Node2D
  1091. setchain.push_back(prev_pos);
  1092. setchain.push_back(codegen.get_name_map_pos(assign_property));
  1093. setchain.push_back(GDScriptFunction::OPCODE_SET_MEMBER);
  1094. }
  1095. for (List<const GDScriptParser::SubscriptNode *>::Element *E = chain.back(); E; E = E->prev()) {
  1096. if (E == chain.front()) { //ignore first
  1097. break;
  1098. }
  1099. const GDScriptParser::SubscriptNode *subscript_elem = E->get();
  1100. int key_idx;
  1101. if (subscript_elem->is_attribute) {
  1102. key_idx = codegen.get_name_map_pos(subscript_elem->attribute->name);
  1103. //printf("named key %x\n",key_idx);
  1104. } else {
  1105. if (prev_pos & (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)) {
  1106. slevel++;
  1107. codegen.alloc_stack(slevel);
  1108. }
  1109. GDScriptParser::ExpressionNode *key = subscript_elem->index;
  1110. key_idx = _parse_expression(codegen, key, slevel);
  1111. //printf("expr key %x\n",key_idx);
  1112. //stack was raised here if retval was stack but..
  1113. }
  1114. if (key_idx < 0) { //error
  1115. return key_idx;
  1116. }
  1117. codegen.opcodes.push_back(subscript_elem->is_attribute ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET);
  1118. codegen.opcodes.push_back(prev_pos);
  1119. codegen.opcodes.push_back(key_idx);
  1120. slevel++;
  1121. codegen.alloc_stack(slevel);
  1122. int dst_pos = (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) | slevel;
  1123. codegen.opcodes.push_back(dst_pos);
  1124. //add in reverse order, since it will be reverted
  1125. setchain.push_back(dst_pos);
  1126. setchain.push_back(key_idx);
  1127. setchain.push_back(prev_pos);
  1128. setchain.push_back(subscript_elem->is_attribute ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET);
  1129. prev_pos = dst_pos;
  1130. }
  1131. setchain.invert();
  1132. int set_index;
  1133. if (subscript->is_attribute) {
  1134. set_index = codegen.get_name_map_pos(subscript->attribute->name);
  1135. } else {
  1136. set_index = _parse_expression(codegen, subscript->index, slevel + 1);
  1137. }
  1138. if (set_index < 0) { //error
  1139. return set_index;
  1140. }
  1141. if (set_index & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
  1142. slevel++;
  1143. codegen.alloc_stack(slevel);
  1144. }
  1145. int set_value = _parse_assign_right_expression(codegen, assignment, slevel + 1, subscript->is_attribute ? 0 : set_index);
  1146. if (set_value < 0) { //error
  1147. return set_value;
  1148. }
  1149. codegen.opcodes.push_back(subscript->is_attribute ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET);
  1150. codegen.opcodes.push_back(prev_pos);
  1151. codegen.opcodes.push_back(set_index);
  1152. codegen.opcodes.push_back(set_value);
  1153. for (int i = 0; i < setchain.size(); i++) {
  1154. codegen.opcodes.push_back(setchain[i]);
  1155. }
  1156. return retval;
  1157. } else if (assignment->assignee->type == GDScriptParser::Node::IDENTIFIER && _is_class_member_property(codegen, static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name)) {
  1158. //assignment to member property
  1159. int slevel = p_stack_level;
  1160. int src_address = _parse_assign_right_expression(codegen, assignment, slevel);
  1161. if (src_address < 0) {
  1162. return -1;
  1163. }
  1164. StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
  1165. codegen.opcodes.push_back(GDScriptFunction::OPCODE_SET_MEMBER);
  1166. codegen.opcodes.push_back(codegen.get_name_map_pos(name));
  1167. codegen.opcodes.push_back(src_address);
  1168. return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
  1169. } else {
  1170. //REGULAR ASSIGNMENT MODE!!
  1171. int slevel = p_stack_level;
  1172. int dst_address_a = -1;
  1173. bool has_setter = false;
  1174. bool is_in_setter = false;
  1175. StringName setter_function;
  1176. if (assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) {
  1177. StringName var_name = static_cast<const GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
  1178. if (!codegen.stack_identifiers.has(var_name) && codegen.script->member_indices.has(var_name)) {
  1179. setter_function = codegen.script->member_indices[var_name].setter;
  1180. if (setter_function != StringName()) {
  1181. has_setter = true;
  1182. is_in_setter = setter_function == codegen.function_name;
  1183. dst_address_a = codegen.script->member_indices[var_name].index;
  1184. }
  1185. }
  1186. }
  1187. if (has_setter) {
  1188. if (is_in_setter) {
  1189. // Use direct member access.
  1190. dst_address_a |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
  1191. } else {
  1192. // Store stack slot for the temp value.
  1193. dst_address_a = slevel++;
  1194. codegen.alloc_stack(slevel);
  1195. dst_address_a |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1196. }
  1197. } else {
  1198. dst_address_a = _parse_expression(codegen, assignment->assignee, slevel);
  1199. if (dst_address_a < 0) {
  1200. return -1;
  1201. }
  1202. if (dst_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
  1203. slevel++;
  1204. codegen.alloc_stack(slevel);
  1205. }
  1206. }
  1207. int src_address_b = _parse_assign_right_expression(codegen, assignment, slevel);
  1208. if (src_address_b < 0) {
  1209. return -1;
  1210. }
  1211. GDScriptDataType assign_type = _gdtype_from_datatype(assignment->assignee->get_datatype());
  1212. if (has_setter && !is_in_setter) {
  1213. // Call setter.
  1214. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL);
  1215. codegen.opcodes.push_back(1); // Argument count.
  1216. codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // Base (self).
  1217. codegen.opcodes.push_back(codegen.get_name_map_pos(setter_function)); // Method name.
  1218. codegen.opcodes.push_back(dst_address_a); // Argument.
  1219. codegen.opcodes.push_back(dst_address_a); // Result address (won't be used here).
  1220. codegen.alloc_call(1);
  1221. } else if (!_generate_typed_assign(codegen, src_address_b, dst_address_a, assign_type, assignment->assigned_value->get_datatype())) {
  1222. return -1;
  1223. }
  1224. return dst_address_a; //if anything, returns wathever was assigned or correct stack position
  1225. }
  1226. } break;
  1227. #undef OPERATOR_RETURN
  1228. //TYPE_TYPE,
  1229. default: {
  1230. ERR_FAIL_V_MSG(-1, "Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); //unreachable code
  1231. } break;
  1232. }
  1233. }
  1234. Error GDScriptCompiler::_parse_match_pattern(CodeGen &codegen, const GDScriptParser::PatternNode *p_pattern, int p_stack_level, int p_value_addr, int p_type_addr, int &r_bound_variables, Vector<int> &r_patch_addresses, Vector<int> &r_block_patch_address) {
  1235. // TODO: Many "repeated" code here that could be abstracted. This compiler is going away when new VM arrives though, so...
  1236. switch (p_pattern->pattern_type) {
  1237. case GDScriptParser::PatternNode::PT_LITERAL: {
  1238. // Get literal type into constant map.
  1239. int literal_type_addr = -1;
  1240. if (!codegen.constant_map.has((int)p_pattern->literal->value.get_type())) {
  1241. literal_type_addr = codegen.constant_map.size();
  1242. codegen.constant_map[(int)p_pattern->literal->value.get_type()] = literal_type_addr;
  1243. } else {
  1244. literal_type_addr = codegen.constant_map[(int)p_pattern->literal->value.get_type()];
  1245. }
  1246. literal_type_addr |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS;
  1247. // Check type equality.
  1248. int equality_addr = p_stack_level++;
  1249. equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1250. codegen.alloc_stack(p_stack_level);
  1251. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1252. codegen.opcodes.push_back(Variant::OP_EQUAL);
  1253. codegen.opcodes.push_back(p_type_addr);
  1254. codegen.opcodes.push_back(literal_type_addr);
  1255. codegen.opcodes.push_back(equality_addr); // Address to result.
  1256. // Jump away if not the same type.
  1257. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1258. codegen.opcodes.push_back(equality_addr);
  1259. r_patch_addresses.push_back(codegen.opcodes.size());
  1260. codegen.opcodes.push_back(0); // Will be replaced.
  1261. // Get literal.
  1262. int literal_addr = _parse_expression(codegen, p_pattern->literal, p_stack_level);
  1263. // Check value equality.
  1264. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1265. codegen.opcodes.push_back(Variant::OP_EQUAL);
  1266. codegen.opcodes.push_back(p_value_addr);
  1267. codegen.opcodes.push_back(literal_addr);
  1268. codegen.opcodes.push_back(equality_addr); // Address to result.
  1269. // Jump away if doesn't match.
  1270. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1271. codegen.opcodes.push_back(equality_addr);
  1272. r_patch_addresses.push_back(codegen.opcodes.size());
  1273. codegen.opcodes.push_back(0); // Will be replaced.
  1274. // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
  1275. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1276. r_block_patch_address.push_back(codegen.opcodes.size());
  1277. codegen.opcodes.push_back(0); // Will be replaced.
  1278. } break;
  1279. case GDScriptParser::PatternNode::PT_EXPRESSION: {
  1280. // Evaluate expression.
  1281. int expr_addr = _parse_expression(codegen, p_pattern->expression, p_stack_level);
  1282. if ((expr_addr >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  1283. p_stack_level++;
  1284. codegen.alloc_stack(p_stack_level);
  1285. }
  1286. // Evaluate expression type.
  1287. int expr_type_addr = p_stack_level++;
  1288. expr_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1289. codegen.alloc_stack(p_stack_level);
  1290. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
  1291. codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
  1292. codegen.opcodes.push_back(1); // One argument.
  1293. codegen.opcodes.push_back(expr_addr); // Argument is the value we want to test.
  1294. codegen.opcodes.push_back(expr_type_addr); // Address to result.
  1295. // Check type equality.
  1296. int equality_addr = p_stack_level++;
  1297. equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1298. codegen.alloc_stack(p_stack_level);
  1299. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1300. codegen.opcodes.push_back(Variant::OP_EQUAL);
  1301. codegen.opcodes.push_back(p_type_addr);
  1302. codegen.opcodes.push_back(expr_type_addr);
  1303. codegen.opcodes.push_back(equality_addr); // Address to result.
  1304. // Jump away if not the same type.
  1305. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1306. codegen.opcodes.push_back(equality_addr);
  1307. r_patch_addresses.push_back(codegen.opcodes.size());
  1308. codegen.opcodes.push_back(0); // Will be replaced.
  1309. // Check value equality.
  1310. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1311. codegen.opcodes.push_back(Variant::OP_EQUAL);
  1312. codegen.opcodes.push_back(p_value_addr);
  1313. codegen.opcodes.push_back(expr_addr);
  1314. codegen.opcodes.push_back(equality_addr); // Address to result.
  1315. // Jump away if doesn't match.
  1316. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1317. codegen.opcodes.push_back(equality_addr);
  1318. r_patch_addresses.push_back(codegen.opcodes.size());
  1319. codegen.opcodes.push_back(0); // Will be replaced.
  1320. // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
  1321. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1322. r_block_patch_address.push_back(codegen.opcodes.size());
  1323. codegen.opcodes.push_back(0); // Will be replaced.
  1324. } break;
  1325. case GDScriptParser::PatternNode::PT_BIND: {
  1326. // Create new stack variable.
  1327. int bind_addr = p_stack_level | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
  1328. codegen.add_stack_identifier(p_pattern->bind->name, p_stack_level++);
  1329. codegen.alloc_stack(p_stack_level);
  1330. r_bound_variables++;
  1331. // Assign value to bound variable.
  1332. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
  1333. codegen.opcodes.push_back(bind_addr); // Destination.
  1334. codegen.opcodes.push_back(p_value_addr); // Source.
  1335. // Not need to block jump because bind happens only once.
  1336. } break;
  1337. case GDScriptParser::PatternNode::PT_ARRAY: {
  1338. int slevel = p_stack_level;
  1339. // Get array type into constant map.
  1340. int array_type_addr = codegen.get_constant_pos(Variant::ARRAY);
  1341. // Check type equality.
  1342. int equality_addr = slevel++;
  1343. equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1344. codegen.alloc_stack(slevel);
  1345. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1346. codegen.opcodes.push_back(Variant::OP_EQUAL);
  1347. codegen.opcodes.push_back(p_type_addr);
  1348. codegen.opcodes.push_back(array_type_addr);
  1349. codegen.opcodes.push_back(equality_addr); // Address to result.
  1350. // Jump away if not the same type.
  1351. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1352. codegen.opcodes.push_back(equality_addr);
  1353. r_patch_addresses.push_back(codegen.opcodes.size());
  1354. codegen.opcodes.push_back(0); // Will be replaced.
  1355. // Store pattern length in constant map.
  1356. int array_length_addr = codegen.get_constant_pos(p_pattern->rest_used ? p_pattern->array.size() - 1 : p_pattern->array.size());
  1357. // Get value length.
  1358. int value_length_addr = slevel++;
  1359. codegen.alloc_stack(slevel);
  1360. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
  1361. codegen.opcodes.push_back(GDScriptFunctions::LEN);
  1362. codegen.opcodes.push_back(1); // One argument.
  1363. codegen.opcodes.push_back(p_value_addr); // Argument is the value we want to test.
  1364. codegen.opcodes.push_back(value_length_addr); // Address to result.
  1365. // Test length compatibility.
  1366. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1367. codegen.opcodes.push_back(p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL);
  1368. codegen.opcodes.push_back(value_length_addr);
  1369. codegen.opcodes.push_back(array_length_addr);
  1370. codegen.opcodes.push_back(equality_addr); // Address to result.
  1371. // Jump away if length is not compatible.
  1372. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1373. codegen.opcodes.push_back(equality_addr);
  1374. r_patch_addresses.push_back(codegen.opcodes.size());
  1375. codegen.opcodes.push_back(0); // Will be replaced.
  1376. // Evaluate element by element.
  1377. for (int i = 0; i < p_pattern->array.size(); i++) {
  1378. if (p_pattern->array[i]->pattern_type == GDScriptParser::PatternNode::PT_REST) {
  1379. // Don't want to access an extra element of the user array.
  1380. break;
  1381. }
  1382. int stlevel = p_stack_level;
  1383. Vector<int> element_block_patches; // I want to internal patterns try the next element instead of going to the block.
  1384. // Add index to constant map.
  1385. int index_addr = codegen.get_constant_pos(i);
  1386. // Get the actual element from the user-sent array.
  1387. int element_addr = stlevel++;
  1388. codegen.alloc_stack(stlevel);
  1389. codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET);
  1390. codegen.opcodes.push_back(p_value_addr); // Source.
  1391. codegen.opcodes.push_back(index_addr); // Index.
  1392. codegen.opcodes.push_back(element_addr); // Destination.
  1393. // Also get type of element.
  1394. int element_type_addr = stlevel++;
  1395. element_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1396. codegen.alloc_stack(stlevel);
  1397. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
  1398. codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
  1399. codegen.opcodes.push_back(1); // One argument.
  1400. codegen.opcodes.push_back(element_addr); // Argument is the value we want to test.
  1401. codegen.opcodes.push_back(element_type_addr); // Address to result.
  1402. // Try the pattern inside the element.
  1403. Error err = _parse_match_pattern(codegen, p_pattern->array[i], stlevel, element_addr, element_type_addr, r_bound_variables, r_patch_addresses, element_block_patches);
  1404. if (err != OK) {
  1405. return err;
  1406. }
  1407. // Patch jumps to block to try the next element.
  1408. for (int j = 0; j < element_block_patches.size(); j++) {
  1409. codegen.opcodes.write[element_block_patches[j]] = codegen.opcodes.size();
  1410. }
  1411. }
  1412. // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
  1413. // Also here for the case of empty arrays.
  1414. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1415. r_block_patch_address.push_back(codegen.opcodes.size());
  1416. codegen.opcodes.push_back(0); // Will be replaced.
  1417. } break;
  1418. case GDScriptParser::PatternNode::PT_DICTIONARY: {
  1419. int slevel = p_stack_level;
  1420. // Get dictionary type into constant map.
  1421. int dict_type_addr = codegen.get_constant_pos(Variant::DICTIONARY);
  1422. // Check type equality.
  1423. int equality_addr = slevel++;
  1424. equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1425. codegen.alloc_stack(slevel);
  1426. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1427. codegen.opcodes.push_back(Variant::OP_EQUAL);
  1428. codegen.opcodes.push_back(p_type_addr);
  1429. codegen.opcodes.push_back(dict_type_addr);
  1430. codegen.opcodes.push_back(equality_addr); // Address to result.
  1431. // Jump away if not the same type.
  1432. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1433. codegen.opcodes.push_back(equality_addr);
  1434. r_patch_addresses.push_back(codegen.opcodes.size());
  1435. codegen.opcodes.push_back(0); // Will be replaced.
  1436. // Store pattern length in constant map.
  1437. int dict_length_addr = codegen.get_constant_pos(p_pattern->rest_used ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size());
  1438. // Get user's dictionary length.
  1439. int value_length_addr = slevel++;
  1440. codegen.alloc_stack(slevel);
  1441. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
  1442. codegen.opcodes.push_back(GDScriptFunctions::LEN);
  1443. codegen.opcodes.push_back(1); // One argument.
  1444. codegen.opcodes.push_back(p_value_addr); // Argument is the value we want to test.
  1445. codegen.opcodes.push_back(value_length_addr); // Address to result.
  1446. // Test length compatibility.
  1447. codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
  1448. codegen.opcodes.push_back(p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL);
  1449. codegen.opcodes.push_back(value_length_addr);
  1450. codegen.opcodes.push_back(dict_length_addr);
  1451. codegen.opcodes.push_back(equality_addr); // Address to result.
  1452. // Jump away if length is not compatible.
  1453. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1454. codegen.opcodes.push_back(equality_addr);
  1455. r_patch_addresses.push_back(codegen.opcodes.size());
  1456. codegen.opcodes.push_back(0); // Will be replaced.
  1457. // Evaluate element by element.
  1458. for (int i = 0; i < p_pattern->dictionary.size(); i++) {
  1459. const GDScriptParser::PatternNode::Pair &element = p_pattern->dictionary[i];
  1460. if (element.value_pattern && element.value_pattern->pattern_type == GDScriptParser::PatternNode::PT_REST) {
  1461. // Ignore rest pattern.
  1462. continue;
  1463. }
  1464. int stlevel = p_stack_level;
  1465. Vector<int> element_block_patches; // I want to internal patterns try the next element instead of going to the block.
  1466. // Get the pattern key.
  1467. int pattern_key_addr = _parse_expression(codegen, element.key, stlevel);
  1468. if (pattern_key_addr < 0) {
  1469. return ERR_PARSE_ERROR;
  1470. }
  1471. if ((pattern_key_addr >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  1472. stlevel++;
  1473. codegen.alloc_stack(stlevel);
  1474. }
  1475. // Create stack slot for test result.
  1476. int test_result = stlevel++;
  1477. test_result |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1478. codegen.alloc_stack(stlevel);
  1479. // Check if pattern key exists in user's dictionary.
  1480. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_RETURN);
  1481. codegen.opcodes.push_back(1); // Argument count.
  1482. codegen.opcodes.push_back(p_value_addr); // Base (user dictionary).
  1483. codegen.opcodes.push_back(codegen.get_name_map_pos("has")); // Function name.
  1484. codegen.opcodes.push_back(pattern_key_addr); // Argument (pattern key).
  1485. codegen.opcodes.push_back(test_result); // Return address.
  1486. // Jump away if key doesn't exist.
  1487. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1488. codegen.opcodes.push_back(test_result);
  1489. r_patch_addresses.push_back(codegen.opcodes.size());
  1490. codegen.opcodes.push_back(0); // Will be replaced.
  1491. if (element.value_pattern != nullptr) {
  1492. // Get actual value from user dictionary.
  1493. int value_addr = stlevel++;
  1494. codegen.alloc_stack(stlevel);
  1495. codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET);
  1496. codegen.opcodes.push_back(p_value_addr); // Source.
  1497. codegen.opcodes.push_back(pattern_key_addr); // Index.
  1498. codegen.opcodes.push_back(value_addr); // Destination.
  1499. // Also get type of value.
  1500. int value_type_addr = stlevel++;
  1501. value_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1502. codegen.alloc_stack(stlevel);
  1503. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
  1504. codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
  1505. codegen.opcodes.push_back(1); // One argument.
  1506. codegen.opcodes.push_back(value_addr); // Argument is the value we want to test.
  1507. codegen.opcodes.push_back(value_type_addr); // Address to result.
  1508. // Try the pattern inside the value.
  1509. Error err = _parse_match_pattern(codegen, element.value_pattern, stlevel, value_addr, value_type_addr, r_bound_variables, r_patch_addresses, element_block_patches);
  1510. if (err != OK) {
  1511. return err;
  1512. }
  1513. }
  1514. // Patch jumps to block to try the next element.
  1515. for (int j = 0; j < element_block_patches.size(); j++) {
  1516. codegen.opcodes.write[element_block_patches[j]] = codegen.opcodes.size();
  1517. }
  1518. }
  1519. // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
  1520. // Also here for the case of empty dictionaries.
  1521. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1522. r_block_patch_address.push_back(codegen.opcodes.size());
  1523. codegen.opcodes.push_back(0); // Will be replaced.
  1524. } break;
  1525. case GDScriptParser::PatternNode::PT_REST:
  1526. // Do nothing.
  1527. break;
  1528. case GDScriptParser::PatternNode::PT_WILDCARD:
  1529. // This matches anything so just do the jump.
  1530. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1531. r_block_patch_address.push_back(codegen.opcodes.size());
  1532. codegen.opcodes.push_back(0); // Will be replaced.
  1533. }
  1534. return OK;
  1535. }
  1536. Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) {
  1537. codegen.push_stack_identifiers();
  1538. int new_identifiers = 0;
  1539. codegen.current_line = p_block->start_line;
  1540. for (int i = 0; i < p_block->statements.size(); i++) {
  1541. const GDScriptParser::Node *s = p_block->statements[i];
  1542. #ifdef DEBUG_ENABLED
  1543. // Add a newline before each statement, since the debugger needs those.
  1544. codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
  1545. codegen.opcodes.push_back(s->start_line);
  1546. codegen.current_line = s->start_line;
  1547. #endif
  1548. switch (s->type) {
  1549. case GDScriptParser::Node::MATCH: {
  1550. const GDScriptParser::MatchNode *match = static_cast<const GDScriptParser::MatchNode *>(s);
  1551. int slevel = p_stack_level;
  1552. // First, let's save the addres of the value match.
  1553. int temp_addr = _parse_expression(codegen, match->test, slevel);
  1554. if (temp_addr < 0) {
  1555. return ERR_PARSE_ERROR;
  1556. }
  1557. if ((temp_addr >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
  1558. slevel++;
  1559. codegen.alloc_stack(slevel);
  1560. }
  1561. // Then, let's save the type of the value in the stack too, so we can reuse for later comparisons.
  1562. int type_addr = slevel++;
  1563. type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
  1564. codegen.alloc_stack(slevel);
  1565. codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
  1566. codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
  1567. codegen.opcodes.push_back(1); // One argument.
  1568. codegen.opcodes.push_back(temp_addr); // Argument is the value we want to test.
  1569. codegen.opcodes.push_back(type_addr); // Address to result.
  1570. Vector<int> patch_match_end; // Will patch the jump to the end of match.
  1571. // Now we can actually start testing.
  1572. // For each branch.
  1573. for (int j = 0; j < match->branches.size(); j++) {
  1574. const GDScriptParser::MatchBranchNode *branch = match->branches[j];
  1575. int bound_variables = 0;
  1576. codegen.push_stack_identifiers(); // Create an extra block around for binds.
  1577. #ifdef DEBUG_ENABLED
  1578. // Add a newline before each branch, since the debugger needs those.
  1579. codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
  1580. codegen.opcodes.push_back(s->start_line);
  1581. codegen.current_line = s->start_line;
  1582. #endif
  1583. Vector<int> patch_addrs; // Will patch with end of pattern to jump.
  1584. Vector<int> block_patch_addrs; // Will patch with start of block to jump.
  1585. // For each pattern in branch.
  1586. for (int k = 0; k < branch->patterns.size(); k++) {
  1587. if (k > 0) {
  1588. // Patch jumps per pattern to allow for multipattern. If a pattern fails it just tries the next.
  1589. for (int l = 0; l < patch_addrs.size(); l++) {
  1590. codegen.opcodes.write[patch_addrs[l]] = codegen.opcodes.size();
  1591. }
  1592. patch_addrs.clear();
  1593. }
  1594. Error err = _parse_match_pattern(codegen, branch->patterns[k], slevel, temp_addr, type_addr, bound_variables, patch_addrs, block_patch_addrs);
  1595. if (err != OK) {
  1596. return err;
  1597. }
  1598. }
  1599. // Patch jumps to the block.
  1600. for (int k = 0; k < block_patch_addrs.size(); k++) {
  1601. codegen.opcodes.write[block_patch_addrs[k]] = codegen.opcodes.size();
  1602. }
  1603. // Leave space for bound variables.
  1604. slevel += bound_variables;
  1605. codegen.alloc_stack(slevel);
  1606. // Parse the branch block.
  1607. _parse_block(codegen, branch->block, slevel, p_break_addr, p_continue_addr);
  1608. // Jump to end of match.
  1609. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1610. patch_match_end.push_back(codegen.opcodes.size());
  1611. codegen.opcodes.push_back(0); // Will be patched.
  1612. // Patch the addresses of last pattern to jump to the end of the branch, into the next one.
  1613. for (int k = 0; k < patch_addrs.size(); k++) {
  1614. codegen.opcodes.write[patch_addrs[k]] = codegen.opcodes.size();
  1615. }
  1616. codegen.pop_stack_identifiers(); // Get out of extra block.
  1617. }
  1618. // Patch the addresses to jump to the end of the match statement.
  1619. for (int j = 0; j < patch_match_end.size(); j++) {
  1620. codegen.opcodes.write[patch_match_end[j]] = codegen.opcodes.size();
  1621. }
  1622. } break;
  1623. case GDScriptParser::Node::IF: {
  1624. const GDScriptParser::IfNode *if_n = static_cast<const GDScriptParser::IfNode *>(s);
  1625. int ret2 = _parse_expression(codegen, if_n->condition, p_stack_level, false);
  1626. if (ret2 < 0) {
  1627. return ERR_PARSE_ERROR;
  1628. }
  1629. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1630. codegen.opcodes.push_back(ret2);
  1631. int else_addr = codegen.opcodes.size();
  1632. codegen.opcodes.push_back(0); //temporary
  1633. Error err = _parse_block(codegen, if_n->true_block, p_stack_level, p_break_addr, p_continue_addr);
  1634. if (err) {
  1635. return err;
  1636. }
  1637. if (if_n->false_block) {
  1638. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1639. int end_addr = codegen.opcodes.size();
  1640. codegen.opcodes.push_back(0);
  1641. codegen.opcodes.write[else_addr] = codegen.opcodes.size();
  1642. Error err2 = _parse_block(codegen, if_n->false_block, p_stack_level, p_break_addr, p_continue_addr);
  1643. if (err2) {
  1644. return err2;
  1645. }
  1646. codegen.opcodes.write[end_addr] = codegen.opcodes.size();
  1647. } else {
  1648. //end without else
  1649. codegen.opcodes.write[else_addr] = codegen.opcodes.size();
  1650. }
  1651. } break;
  1652. case GDScriptParser::Node::FOR: {
  1653. const GDScriptParser::ForNode *for_n = static_cast<const GDScriptParser::ForNode *>(s);
  1654. int slevel = p_stack_level;
  1655. int iter_stack_pos = slevel;
  1656. int iterator_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  1657. int counter_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  1658. int container_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  1659. codegen.alloc_stack(slevel);
  1660. codegen.push_stack_identifiers();
  1661. codegen.add_stack_identifier(for_n->variable->name, iter_stack_pos);
  1662. int ret2 = _parse_expression(codegen, for_n->list, slevel, false);
  1663. if (ret2 < 0) {
  1664. return ERR_COMPILATION_FAILED;
  1665. }
  1666. //assign container
  1667. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
  1668. codegen.opcodes.push_back(container_pos);
  1669. codegen.opcodes.push_back(ret2);
  1670. //begin loop
  1671. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ITERATE_BEGIN);
  1672. codegen.opcodes.push_back(counter_pos);
  1673. codegen.opcodes.push_back(container_pos);
  1674. codegen.opcodes.push_back(codegen.opcodes.size() + 4);
  1675. codegen.opcodes.push_back(iterator_pos);
  1676. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); //skip code for next
  1677. codegen.opcodes.push_back(codegen.opcodes.size() + 8);
  1678. //break loop
  1679. int break_pos = codegen.opcodes.size();
  1680. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); //skip code for next
  1681. codegen.opcodes.push_back(0); //skip code for next
  1682. //next loop
  1683. int continue_pos = codegen.opcodes.size();
  1684. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ITERATE);
  1685. codegen.opcodes.push_back(counter_pos);
  1686. codegen.opcodes.push_back(container_pos);
  1687. codegen.opcodes.push_back(break_pos);
  1688. codegen.opcodes.push_back(iterator_pos);
  1689. Error err = _parse_block(codegen, for_n->loop, slevel, break_pos, continue_pos);
  1690. if (err) {
  1691. return err;
  1692. }
  1693. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1694. codegen.opcodes.push_back(continue_pos);
  1695. codegen.opcodes.write[break_pos + 1] = codegen.opcodes.size();
  1696. codegen.pop_stack_identifiers();
  1697. } break;
  1698. case GDScriptParser::Node::WHILE: {
  1699. const GDScriptParser::WhileNode *while_n = static_cast<const GDScriptParser::WhileNode *>(s);
  1700. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1701. codegen.opcodes.push_back(codegen.opcodes.size() + 3);
  1702. int break_addr = codegen.opcodes.size();
  1703. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1704. codegen.opcodes.push_back(0);
  1705. int continue_addr = codegen.opcodes.size();
  1706. int ret2 = _parse_expression(codegen, while_n->condition, p_stack_level, false);
  1707. if (ret2 < 0) {
  1708. return ERR_PARSE_ERROR;
  1709. }
  1710. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
  1711. codegen.opcodes.push_back(ret2);
  1712. codegen.opcodes.push_back(break_addr);
  1713. Error err = _parse_block(codegen, while_n->loop, p_stack_level, break_addr, continue_addr);
  1714. if (err) {
  1715. return err;
  1716. }
  1717. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1718. codegen.opcodes.push_back(continue_addr);
  1719. codegen.opcodes.write[break_addr + 1] = codegen.opcodes.size();
  1720. } break;
  1721. case GDScriptParser::Node::BREAK: {
  1722. if (p_break_addr < 0) {
  1723. _set_error("'break'' not within loop", s);
  1724. return ERR_COMPILATION_FAILED;
  1725. }
  1726. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1727. codegen.opcodes.push_back(p_break_addr);
  1728. } break;
  1729. case GDScriptParser::Node::CONTINUE: {
  1730. if (p_continue_addr < 0) {
  1731. _set_error("'continue' not within loop", s);
  1732. return ERR_COMPILATION_FAILED;
  1733. }
  1734. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
  1735. codegen.opcodes.push_back(p_continue_addr);
  1736. } break;
  1737. case GDScriptParser::Node::RETURN: {
  1738. const GDScriptParser::ReturnNode *return_n = static_cast<const GDScriptParser::ReturnNode *>(s);
  1739. int ret2;
  1740. if (return_n->return_value != nullptr) {
  1741. ret2 = _parse_expression(codegen, return_n->return_value, p_stack_level, false);
  1742. if (ret2 < 0) {
  1743. return ERR_PARSE_ERROR;
  1744. }
  1745. } else {
  1746. ret2 = GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
  1747. }
  1748. codegen.opcodes.push_back(GDScriptFunction::OPCODE_RETURN);
  1749. codegen.opcodes.push_back(ret2);
  1750. } break;
  1751. case GDScriptParser::Node::ASSERT: {
  1752. #ifdef DEBUG_ENABLED
  1753. // try subblocks
  1754. const GDScriptParser::AssertNode *as = static_cast<const GDScriptParser::AssertNode *>(s);
  1755. int ret2 = _parse_expression(codegen, as->condition, p_stack_level, false);
  1756. if (ret2 < 0) {
  1757. return ERR_PARSE_ERROR;
  1758. }
  1759. int message_ret = 0;
  1760. if (as->message) {
  1761. message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false);
  1762. if (message_ret < 0) {
  1763. return ERR_PARSE_ERROR;
  1764. }
  1765. }
  1766. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT);
  1767. codegen.opcodes.push_back(ret2);
  1768. codegen.opcodes.push_back(message_ret);
  1769. #endif
  1770. } break;
  1771. case GDScriptParser::Node::BREAKPOINT: {
  1772. #ifdef DEBUG_ENABLED
  1773. // try subblocks
  1774. codegen.opcodes.push_back(GDScriptFunction::OPCODE_BREAKPOINT);
  1775. #endif
  1776. } break;
  1777. case GDScriptParser::Node::VARIABLE: {
  1778. const GDScriptParser::VariableNode *lv = static_cast<const GDScriptParser::VariableNode *>(s);
  1779. // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
  1780. //
  1781. //if (_is_class_member_property(codegen, lv->name)) {
  1782. // _set_error("Name for local variable '" + String(lv->name) + "' can't shadow class property of the same name.", lv);
  1783. // return ERR_ALREADY_EXISTS;
  1784. //}
  1785. codegen.add_stack_identifier(lv->identifier->name, p_stack_level++);
  1786. codegen.alloc_stack(p_stack_level);
  1787. new_identifiers++;
  1788. if (lv->initializer != nullptr) {
  1789. int dst_address = codegen.stack_identifiers[lv->identifier->name];
  1790. dst_address |= GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS;
  1791. int src_address = _parse_expression(codegen, lv->initializer, p_stack_level);
  1792. if (src_address < 0) {
  1793. return ERR_PARSE_ERROR;
  1794. }
  1795. if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(lv->get_datatype()), lv->initializer->get_datatype())) {
  1796. return ERR_PARSE_ERROR;
  1797. }
  1798. }
  1799. } break;
  1800. case GDScriptParser::Node::CONSTANT: {
  1801. // Local constants.
  1802. const GDScriptParser::ConstantNode *lc = static_cast<const GDScriptParser::ConstantNode *>(s);
  1803. if (!lc->initializer->is_constant) {
  1804. _set_error("Local constant must have a constant value as initializer.", lc->initializer);
  1805. return ERR_PARSE_ERROR;
  1806. }
  1807. codegen.local_named_constants[lc->identifier->name] = codegen.get_constant_pos(lc->initializer->reduced_value);
  1808. } break;
  1809. case GDScriptParser::Node::PASS:
  1810. // Nothing to do.
  1811. break;
  1812. default: {
  1813. //expression
  1814. if (s->is_expression()) {
  1815. int ret2 = _parse_expression(codegen, static_cast<const GDScriptParser::ExpressionNode *>(s), p_stack_level, true);
  1816. if (ret2 < 0) {
  1817. return ERR_PARSE_ERROR;
  1818. }
  1819. } else {
  1820. ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Bug in bytecode compiler, unexpected node in parse tree while parsing statement."); //unreachable code
  1821. }
  1822. } break;
  1823. }
  1824. }
  1825. codegen.pop_stack_identifiers();
  1826. return OK;
  1827. }
  1828. Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) {
  1829. Vector<int> bytecode;
  1830. CodeGen codegen;
  1831. codegen.class_node = p_class;
  1832. codegen.script = p_script;
  1833. codegen.function_node = p_func;
  1834. codegen.stack_max = 0;
  1835. codegen.current_line = 0;
  1836. codegen.call_max = 0;
  1837. codegen.debug_stack = EngineDebugger::is_active();
  1838. Vector<StringName> argnames;
  1839. int stack_level = 0;
  1840. int optional_parameters = 0;
  1841. if (p_func) {
  1842. for (int i = 0; i < p_func->parameters.size(); i++) {
  1843. // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
  1844. //
  1845. //if (_is_class_member_property(p_script, p_func->arguments[i])) {
  1846. // _set_error("Name for argument '" + String(p_func->arguments[i]) + "' can't shadow class property of the same name.", p_func);
  1847. // return ERR_ALREADY_EXISTS;
  1848. //}
  1849. codegen.add_stack_identifier(p_func->parameters[i]->identifier->name, i);
  1850. #ifdef TOOLS_ENABLED
  1851. argnames.push_back(p_func->parameters[i]->identifier->name);
  1852. #endif
  1853. if (p_func->parameters[i]->default_value != nullptr) {
  1854. optional_parameters++;
  1855. }
  1856. }
  1857. stack_level = p_func->parameters.size();
  1858. }
  1859. codegen.alloc_stack(stack_level);
  1860. /* Parse initializer -if applies- */
  1861. bool is_implicit_initializer = !p_for_ready && !p_func;
  1862. bool is_initializer = p_func && String(p_func->identifier->name) == GDScriptLanguage::get_singleton()->strings._init;
  1863. if (is_implicit_initializer) {
  1864. // Initialize class fields.
  1865. for (int i = 0; i < p_class->members.size(); i++) {
  1866. if (p_class->members[i].type != GDScriptParser::ClassNode::Member::VARIABLE) {
  1867. continue;
  1868. }
  1869. const GDScriptParser::VariableNode *field = p_class->members[i].variable;
  1870. if (field->onready) {
  1871. // Only initialize in _ready.
  1872. continue;
  1873. }
  1874. if (field->initializer) {
  1875. // Emit proper line change.
  1876. codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
  1877. codegen.opcodes.push_back(field->initializer->start_line);
  1878. int src_address = _parse_expression(codegen, field->initializer, stack_level, false, true);
  1879. if (src_address < 0) {
  1880. return ERR_PARSE_ERROR;
  1881. }
  1882. int dst_address = codegen.script->member_indices[field->identifier->name].index;
  1883. dst_address |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
  1884. if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(field->get_datatype()), field->initializer->get_datatype())) {
  1885. return ERR_PARSE_ERROR;
  1886. }
  1887. }
  1888. }
  1889. }
  1890. if (p_for_ready || (p_func && String(p_func->identifier->name) == "_ready")) {
  1891. // Initialize class fields on ready.
  1892. for (int i = 0; i < p_class->members.size(); i++) {
  1893. if (p_class->members[i].type != GDScriptParser::ClassNode::Member::VARIABLE) {
  1894. continue;
  1895. }
  1896. const GDScriptParser::VariableNode *field = p_class->members[i].variable;
  1897. if (!field->onready) {
  1898. continue;
  1899. }
  1900. if (field->initializer) {
  1901. // Emit proper line change.
  1902. codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
  1903. codegen.opcodes.push_back(field->initializer->start_line);
  1904. int src_address = _parse_expression(codegen, field->initializer, stack_level, false, true);
  1905. if (src_address < 0) {
  1906. return ERR_PARSE_ERROR;
  1907. }
  1908. int dst_address = codegen.script->member_indices[field->identifier->name].index;
  1909. dst_address |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
  1910. if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(field->get_datatype()), field->initializer->get_datatype())) {
  1911. return ERR_PARSE_ERROR;
  1912. }
  1913. }
  1914. }
  1915. }
  1916. /* Parse default argument code -if applies- */
  1917. Vector<int> defarg_addr;
  1918. StringName func_name;
  1919. if (p_func) {
  1920. if (optional_parameters > 0) {
  1921. codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT);
  1922. defarg_addr.push_back(codegen.opcodes.size());
  1923. for (int i = p_func->parameters.size() - optional_parameters; i < p_func->parameters.size(); i++) {
  1924. int src_addr = _parse_expression(codegen, p_func->parameters[i]->default_value, stack_level, true);
  1925. if (src_addr < 0) {
  1926. return ERR_PARSE_ERROR;
  1927. }
  1928. int dst_addr = codegen.stack_identifiers[p_func->parameters[i]->identifier->name] | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
  1929. if (!_generate_typed_assign(codegen, src_addr, dst_addr, _gdtype_from_datatype(p_func->parameters[i]->get_datatype()), p_func->parameters[i]->default_value->get_datatype())) {
  1930. return ERR_PARSE_ERROR;
  1931. }
  1932. defarg_addr.push_back(codegen.opcodes.size());
  1933. }
  1934. defarg_addr.invert();
  1935. }
  1936. func_name = p_func->identifier->name;
  1937. codegen.function_name = func_name;
  1938. Error err = _parse_block(codegen, p_func->body, stack_level);
  1939. if (err) {
  1940. return err;
  1941. }
  1942. } else {
  1943. if (p_for_ready) {
  1944. func_name = "_ready";
  1945. } else {
  1946. func_name = "@implicit_new";
  1947. }
  1948. }
  1949. codegen.function_name = func_name;
  1950. codegen.opcodes.push_back(GDScriptFunction::OPCODE_END);
  1951. /*
  1952. if (String(p_func->name)=="") { //initializer func
  1953. gdfunc = &p_script->initializer;
  1954. */
  1955. //} else { //regular func
  1956. p_script->member_functions[func_name] = memnew(GDScriptFunction);
  1957. GDScriptFunction *gdfunc = p_script->member_functions[func_name];
  1958. //}
  1959. if (p_func) {
  1960. gdfunc->_static = p_func->is_static;
  1961. gdfunc->rpc_mode = p_func->rpc_mode;
  1962. gdfunc->argument_types.resize(p_func->parameters.size());
  1963. for (int i = 0; i < p_func->parameters.size(); i++) {
  1964. gdfunc->argument_types.write[i] = _gdtype_from_datatype(p_func->parameters[i]->get_datatype());
  1965. }
  1966. gdfunc->return_type = _gdtype_from_datatype(p_func->get_datatype());
  1967. } else {
  1968. gdfunc->_static = false;
  1969. gdfunc->rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
  1970. gdfunc->return_type = GDScriptDataType();
  1971. gdfunc->return_type.has_type = true;
  1972. gdfunc->return_type.kind = GDScriptDataType::BUILTIN;
  1973. gdfunc->return_type.builtin_type = Variant::NIL;
  1974. }
  1975. #ifdef TOOLS_ENABLED
  1976. gdfunc->arg_names = argnames;
  1977. #endif
  1978. //constants
  1979. if (codegen.constant_map.size()) {
  1980. gdfunc->_constant_count = codegen.constant_map.size();
  1981. gdfunc->constants.resize(codegen.constant_map.size());
  1982. gdfunc->_constants_ptr = gdfunc->constants.ptrw();
  1983. const Variant *K = nullptr;
  1984. while ((K = codegen.constant_map.next(K))) {
  1985. int idx = codegen.constant_map[*K];
  1986. gdfunc->constants.write[idx] = *K;
  1987. }
  1988. } else {
  1989. gdfunc->_constants_ptr = nullptr;
  1990. gdfunc->_constant_count = 0;
  1991. }
  1992. //global names
  1993. if (codegen.name_map.size()) {
  1994. gdfunc->global_names.resize(codegen.name_map.size());
  1995. gdfunc->_global_names_ptr = &gdfunc->global_names[0];
  1996. for (Map<StringName, int>::Element *E = codegen.name_map.front(); E; E = E->next()) {
  1997. gdfunc->global_names.write[E->get()] = E->key();
  1998. }
  1999. gdfunc->_global_names_count = gdfunc->global_names.size();
  2000. } else {
  2001. gdfunc->_global_names_ptr = nullptr;
  2002. gdfunc->_global_names_count = 0;
  2003. }
  2004. #ifdef TOOLS_ENABLED
  2005. // Named globals
  2006. if (codegen.named_globals.size()) {
  2007. gdfunc->named_globals.resize(codegen.named_globals.size());
  2008. gdfunc->_named_globals_ptr = gdfunc->named_globals.ptr();
  2009. for (int i = 0; i < codegen.named_globals.size(); i++) {
  2010. gdfunc->named_globals.write[i] = codegen.named_globals[i];
  2011. }
  2012. gdfunc->_named_globals_count = gdfunc->named_globals.size();
  2013. }
  2014. #endif
  2015. if (codegen.opcodes.size()) {
  2016. gdfunc->code = codegen.opcodes;
  2017. gdfunc->_code_ptr = &gdfunc->code[0];
  2018. gdfunc->_code_size = codegen.opcodes.size();
  2019. } else {
  2020. gdfunc->_code_ptr = nullptr;
  2021. gdfunc->_code_size = 0;
  2022. }
  2023. if (defarg_addr.size()) {
  2024. gdfunc->default_arguments = defarg_addr;
  2025. gdfunc->_default_arg_count = defarg_addr.size() - 1;
  2026. gdfunc->_default_arg_ptr = &gdfunc->default_arguments[0];
  2027. } else {
  2028. gdfunc->_default_arg_count = 0;
  2029. gdfunc->_default_arg_ptr = nullptr;
  2030. }
  2031. gdfunc->_argument_count = p_func ? p_func->parameters.size() : 0;
  2032. gdfunc->_stack_size = codegen.stack_max;
  2033. gdfunc->_call_size = codegen.call_max;
  2034. gdfunc->name = func_name;
  2035. #ifdef DEBUG_ENABLED
  2036. if (EngineDebugger::is_active()) {
  2037. String signature;
  2038. //path
  2039. if (p_script->get_path() != String()) {
  2040. signature += p_script->get_path();
  2041. }
  2042. //loc
  2043. if (p_func) {
  2044. signature += "::" + itos(p_func->body->start_line);
  2045. } else {
  2046. signature += "::0";
  2047. }
  2048. //function and class
  2049. if (p_class->identifier) {
  2050. signature += "::" + String(p_class->identifier->name) + "." + String(func_name);
  2051. } else {
  2052. signature += "::" + String(func_name);
  2053. }
  2054. gdfunc->profile.signature = signature;
  2055. }
  2056. #endif
  2057. gdfunc->_script = p_script;
  2058. gdfunc->source = source;
  2059. #ifdef DEBUG_ENABLED
  2060. {
  2061. gdfunc->func_cname = (String(source) + " - " + String(func_name)).utf8();
  2062. gdfunc->_func_cname = gdfunc->func_cname.get_data();
  2063. }
  2064. #endif
  2065. if (p_func) {
  2066. gdfunc->_initial_line = p_func->start_line;
  2067. #ifdef TOOLS_ENABLED
  2068. p_script->member_lines[func_name] = p_func->start_line;
  2069. #endif
  2070. } else {
  2071. gdfunc->_initial_line = 0;
  2072. }
  2073. if (codegen.debug_stack) {
  2074. gdfunc->stack_debug = codegen.stack_debug;
  2075. }
  2076. if (is_initializer) {
  2077. p_script->initializer = gdfunc;
  2078. }
  2079. if (is_implicit_initializer) {
  2080. p_script->implicit_initializer = gdfunc;
  2081. }
  2082. return OK;
  2083. }
  2084. Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::VariableNode *p_variable, bool p_is_setter) {
  2085. Vector<int> bytecode;
  2086. CodeGen codegen;
  2087. codegen.class_node = p_class;
  2088. codegen.script = p_script;
  2089. codegen.function_node = nullptr;
  2090. codegen.stack_max = 0;
  2091. codegen.current_line = 0;
  2092. codegen.call_max = 0;
  2093. codegen.debug_stack = EngineDebugger::is_active();
  2094. Vector<StringName> argnames;
  2095. int stack_level = 0;
  2096. if (p_is_setter) {
  2097. codegen.add_stack_identifier(p_variable->setter_parameter->name, stack_level++);
  2098. argnames.push_back(p_variable->setter_parameter->name);
  2099. }
  2100. codegen.alloc_stack(stack_level);
  2101. StringName func_name;
  2102. if (p_is_setter) {
  2103. func_name = "@" + p_variable->identifier->name + "_setter";
  2104. } else {
  2105. func_name = "@" + p_variable->identifier->name + "_getter";
  2106. }
  2107. codegen.function_name = func_name;
  2108. Error err = _parse_block(codegen, p_is_setter ? p_variable->setter : p_variable->getter, stack_level);
  2109. if (err != OK) {
  2110. return err;
  2111. }
  2112. codegen.opcodes.push_back(GDScriptFunction::OPCODE_END);
  2113. p_script->member_functions[func_name] = memnew(GDScriptFunction);
  2114. GDScriptFunction *gdfunc = p_script->member_functions[func_name];
  2115. gdfunc->_static = false;
  2116. gdfunc->rpc_mode = p_variable->rpc_mode;
  2117. gdfunc->argument_types.resize(p_is_setter ? 1 : 0);
  2118. gdfunc->return_type = _gdtype_from_datatype(p_variable->get_datatype());
  2119. #ifdef TOOLS_ENABLED
  2120. gdfunc->arg_names = argnames;
  2121. #endif
  2122. // TODO: Unify this with function compiler.
  2123. //constants
  2124. if (codegen.constant_map.size()) {
  2125. gdfunc->_constant_count = codegen.constant_map.size();
  2126. gdfunc->constants.resize(codegen.constant_map.size());
  2127. gdfunc->_constants_ptr = gdfunc->constants.ptrw();
  2128. const Variant *K = nullptr;
  2129. while ((K = codegen.constant_map.next(K))) {
  2130. int idx = codegen.constant_map[*K];
  2131. gdfunc->constants.write[idx] = *K;
  2132. }
  2133. } else {
  2134. gdfunc->_constants_ptr = nullptr;
  2135. gdfunc->_constant_count = 0;
  2136. }
  2137. //global names
  2138. if (codegen.name_map.size()) {
  2139. gdfunc->global_names.resize(codegen.name_map.size());
  2140. gdfunc->_global_names_ptr = &gdfunc->global_names[0];
  2141. for (Map<StringName, int>::Element *E = codegen.name_map.front(); E; E = E->next()) {
  2142. gdfunc->global_names.write[E->get()] = E->key();
  2143. }
  2144. gdfunc->_global_names_count = gdfunc->global_names.size();
  2145. } else {
  2146. gdfunc->_global_names_ptr = nullptr;
  2147. gdfunc->_global_names_count = 0;
  2148. }
  2149. #ifdef TOOLS_ENABLED
  2150. // Named globals
  2151. if (codegen.named_globals.size()) {
  2152. gdfunc->named_globals.resize(codegen.named_globals.size());
  2153. gdfunc->_named_globals_ptr = gdfunc->named_globals.ptr();
  2154. for (int i = 0; i < codegen.named_globals.size(); i++) {
  2155. gdfunc->named_globals.write[i] = codegen.named_globals[i];
  2156. }
  2157. gdfunc->_named_globals_count = gdfunc->named_globals.size();
  2158. }
  2159. #endif
  2160. gdfunc->code = codegen.opcodes;
  2161. gdfunc->_code_ptr = &gdfunc->code[0];
  2162. gdfunc->_code_size = codegen.opcodes.size();
  2163. gdfunc->_default_arg_count = 0;
  2164. gdfunc->_default_arg_ptr = nullptr;
  2165. gdfunc->_argument_count = argnames.size();
  2166. gdfunc->_stack_size = codegen.stack_max;
  2167. gdfunc->_call_size = codegen.call_max;
  2168. gdfunc->name = func_name;
  2169. #ifdef DEBUG_ENABLED
  2170. if (EngineDebugger::is_active()) {
  2171. String signature;
  2172. //path
  2173. if (p_script->get_path() != String()) {
  2174. signature += p_script->get_path();
  2175. }
  2176. //loc
  2177. signature += "::" + itos(p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line);
  2178. //function and class
  2179. if (p_class->identifier) {
  2180. signature += "::" + String(p_class->identifier->name) + "." + String(func_name);
  2181. } else {
  2182. signature += "::" + String(func_name);
  2183. }
  2184. gdfunc->profile.signature = signature;
  2185. }
  2186. #endif
  2187. gdfunc->_script = p_script;
  2188. gdfunc->source = source;
  2189. #ifdef DEBUG_ENABLED
  2190. {
  2191. gdfunc->func_cname = (String(source) + " - " + String(func_name)).utf8();
  2192. gdfunc->_func_cname = gdfunc->func_cname.get_data();
  2193. }
  2194. #endif
  2195. gdfunc->_initial_line = p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line;
  2196. #ifdef TOOLS_ENABLED
  2197. p_script->member_lines[func_name] = gdfunc->_initial_line;
  2198. #endif
  2199. if (codegen.debug_stack) {
  2200. gdfunc->stack_debug = codegen.stack_debug;
  2201. }
  2202. return OK;
  2203. }
  2204. Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
  2205. parsing_classes.insert(p_script);
  2206. if (p_class->outer && p_class->outer->outer) {
  2207. // Owner is not root
  2208. if (!parsed_classes.has(p_script->_owner)) {
  2209. if (parsing_classes.has(p_script->_owner)) {
  2210. _set_error("Cyclic class reference for '" + String(p_class->identifier->name) + "'.", p_class);
  2211. return ERR_PARSE_ERROR;
  2212. }
  2213. Error err = _parse_class_level(p_script->_owner, p_class->outer, p_keep_state);
  2214. if (err) {
  2215. return err;
  2216. }
  2217. }
  2218. }
  2219. p_script->native = Ref<GDScriptNativeClass>();
  2220. p_script->base = Ref<GDScript>();
  2221. p_script->_base = nullptr;
  2222. p_script->members.clear();
  2223. p_script->constants.clear();
  2224. for (Map<StringName, GDScriptFunction *>::Element *E = p_script->member_functions.front(); E; E = E->next()) {
  2225. memdelete(E->get());
  2226. }
  2227. p_script->member_functions.clear();
  2228. p_script->member_indices.clear();
  2229. p_script->member_info.clear();
  2230. p_script->_signals.clear();
  2231. p_script->initializer = nullptr;
  2232. p_script->tool = parser->is_tool();
  2233. p_script->name = p_class->identifier ? p_class->identifier->name : "";
  2234. Ref<GDScriptNativeClass> native;
  2235. GDScriptDataType base_type = _gdtype_from_datatype(p_class->base_type);
  2236. // Inheritance
  2237. switch (base_type.kind) {
  2238. case GDScriptDataType::NATIVE: {
  2239. int native_idx = GDScriptLanguage::get_singleton()->get_global_map()[base_type.native_type];
  2240. native = GDScriptLanguage::get_singleton()->get_global_array()[native_idx];
  2241. ERR_FAIL_COND_V(native.is_null(), ERR_BUG);
  2242. p_script->native = native;
  2243. } break;
  2244. case GDScriptDataType::GDSCRIPT: {
  2245. Ref<GDScript> base = base_type.script_type;
  2246. p_script->base = base;
  2247. p_script->_base = base.ptr();
  2248. if (p_class->base_type.kind == GDScriptParser::DataType::CLASS && p_class->base_type.class_type != nullptr) {
  2249. if (!parsed_classes.has(p_script->_base)) {
  2250. if (parsing_classes.has(p_script->_base)) {
  2251. String class_name = p_class->identifier ? p_class->identifier->name : "<main>";
  2252. _set_error("Cyclic class reference for '" + class_name + "'.", p_class);
  2253. return ERR_PARSE_ERROR;
  2254. }
  2255. Error err = _parse_class_level(p_script->_base, p_class->base_type.class_type, p_keep_state);
  2256. if (err) {
  2257. return err;
  2258. }
  2259. }
  2260. }
  2261. p_script->member_indices = base->member_indices;
  2262. } break;
  2263. default: {
  2264. _set_error("Parser bug: invalid inheritance.", p_class);
  2265. return ERR_BUG;
  2266. } break;
  2267. }
  2268. for (int i = 0; i < p_class->members.size(); i++) {
  2269. const GDScriptParser::ClassNode::Member &member = p_class->members[i];
  2270. switch (member.type) {
  2271. case GDScriptParser::ClassNode::Member::VARIABLE: {
  2272. const GDScriptParser::VariableNode *variable = member.variable;
  2273. StringName name = variable->identifier->name;
  2274. GDScript::MemberInfo minfo;
  2275. minfo.index = p_script->member_indices.size();
  2276. switch (variable->property) {
  2277. case GDScriptParser::VariableNode::PROP_NONE:
  2278. break; // Nothing to do.
  2279. case GDScriptParser::VariableNode::PROP_SETGET:
  2280. if (variable->setter_pointer != nullptr) {
  2281. minfo.setter = variable->setter_pointer->name;
  2282. }
  2283. if (variable->getter_pointer != nullptr) {
  2284. minfo.getter = variable->getter_pointer->name;
  2285. }
  2286. break;
  2287. case GDScriptParser::VariableNode::PROP_INLINE:
  2288. if (variable->setter != nullptr) {
  2289. minfo.setter = "@" + variable->identifier->name + "_setter";
  2290. }
  2291. if (variable->getter != nullptr) {
  2292. minfo.getter = "@" + variable->identifier->name + "_getter";
  2293. }
  2294. break;
  2295. }
  2296. minfo.rpc_mode = variable->rpc_mode;
  2297. minfo.data_type = _gdtype_from_datatype(variable->get_datatype());
  2298. PropertyInfo prop_info = minfo.data_type;
  2299. prop_info.name = name;
  2300. PropertyInfo export_info = variable->export_info;
  2301. if (variable->exported) {
  2302. if (!minfo.data_type.has_type) {
  2303. prop_info.type = export_info.type;
  2304. prop_info.class_name = export_info.class_name;
  2305. }
  2306. prop_info.hint = export_info.hint;
  2307. prop_info.hint_string = export_info.hint_string;
  2308. prop_info.usage = export_info.usage;
  2309. #ifdef TOOLS_ENABLED
  2310. if (variable->initializer != nullptr && variable->initializer->type == GDScriptParser::Node::LITERAL) {
  2311. p_script->member_default_values[name] = static_cast<const GDScriptParser::LiteralNode *>(variable->initializer)->value;
  2312. }
  2313. #endif
  2314. } else {
  2315. prop_info.usage = PROPERTY_USAGE_SCRIPT_VARIABLE;
  2316. }
  2317. p_script->member_info[name] = prop_info;
  2318. p_script->member_indices[name] = minfo;
  2319. p_script->members.insert(name);
  2320. #ifdef TOOLS_ENABLED
  2321. p_script->member_lines[name] = variable->start_line;
  2322. #endif
  2323. } break;
  2324. case GDScriptParser::ClassNode::Member::CONSTANT: {
  2325. const GDScriptParser::ConstantNode *constant = member.constant;
  2326. StringName name = constant->identifier->name;
  2327. ERR_CONTINUE(constant->initializer->type != GDScriptParser::Node::LITERAL);
  2328. const GDScriptParser::LiteralNode *literal = static_cast<const GDScriptParser::LiteralNode *>(constant->initializer);
  2329. p_script->constants.insert(name, literal->value);
  2330. #ifdef TOOLS_ENABLED
  2331. p_script->member_lines[name] = constant->start_line;
  2332. #endif
  2333. } break;
  2334. case GDScriptParser::ClassNode::Member::ENUM_VALUE: {
  2335. const GDScriptParser::EnumNode::Value &enum_value = member.enum_value;
  2336. StringName name = enum_value.identifier->name;
  2337. p_script->constants.insert(name, enum_value.value);
  2338. #ifdef TOOLS_ENABLED
  2339. p_script->member_lines[name] = enum_value.identifier->start_line;
  2340. #endif
  2341. } break;
  2342. case GDScriptParser::ClassNode::Member::SIGNAL: {
  2343. const GDScriptParser::SignalNode *signal = member.signal;
  2344. StringName name = signal->identifier->name;
  2345. GDScript *c = p_script;
  2346. while (c) {
  2347. if (c->_signals.has(name)) {
  2348. _set_error("Signal '" + name + "' redefined (in current or parent class)", p_class);
  2349. return ERR_ALREADY_EXISTS;
  2350. }
  2351. if (c->base.is_valid()) {
  2352. c = c->base.ptr();
  2353. } else {
  2354. c = nullptr;
  2355. }
  2356. }
  2357. if (native.is_valid()) {
  2358. if (ClassDB::has_signal(native->get_name(), name)) {
  2359. _set_error("Signal '" + name + "' redefined (original in native class '" + String(native->get_name()) + "')", p_class);
  2360. return ERR_ALREADY_EXISTS;
  2361. }
  2362. }
  2363. Vector<StringName> parameters_names;
  2364. parameters_names.resize(signal->parameters.size());
  2365. for (int j = 0; j < signal->parameters.size(); j++) {
  2366. parameters_names.write[j] = signal->parameters[j]->identifier->name;
  2367. }
  2368. p_script->_signals[name] = parameters_names;
  2369. } break;
  2370. case GDScriptParser::ClassNode::Member::ENUM: {
  2371. const GDScriptParser::EnumNode *enum_n = member.m_enum;
  2372. // TODO: Make enums not be just a dictionary?
  2373. Dictionary new_enum;
  2374. for (int j = 0; j < enum_n->values.size(); j++) {
  2375. int value = enum_n->values[j].value;
  2376. // Needs to be string because Variant::get will convert to String.
  2377. new_enum[String(enum_n->values[j].identifier->name)] = value;
  2378. }
  2379. p_script->constants.insert(enum_n->identifier->name, new_enum);
  2380. #ifdef TOOLS_ENABLED
  2381. p_script->member_lines[enum_n->identifier->name] = enum_n->start_line;
  2382. #endif
  2383. } break;
  2384. default:
  2385. break; // Nothing to do here.
  2386. }
  2387. }
  2388. parsed_classes.insert(p_script);
  2389. parsing_classes.erase(p_script);
  2390. //parse sub-classes
  2391. for (int i = 0; i < p_class->members.size(); i++) {
  2392. const GDScriptParser::ClassNode::Member &member = p_class->members[i];
  2393. if (member.type != member.CLASS) {
  2394. continue;
  2395. }
  2396. const GDScriptParser::ClassNode *inner_class = member.m_class;
  2397. StringName name = inner_class->identifier->name;
  2398. Ref<GDScript> &subclass = p_script->subclasses[name];
  2399. GDScript *subclass_ptr = subclass.ptr();
  2400. // Subclass might still be parsing, just skip it
  2401. if (!parsed_classes.has(subclass_ptr) && !parsing_classes.has(subclass_ptr)) {
  2402. Error err = _parse_class_level(subclass_ptr, inner_class, p_keep_state);
  2403. if (err) {
  2404. return err;
  2405. }
  2406. }
  2407. #ifdef TOOLS_ENABLED
  2408. p_script->member_lines[name] = inner_class->start_line;
  2409. #endif
  2410. p_script->constants.insert(name, subclass); //once parsed, goes to the list of constants
  2411. }
  2412. return OK;
  2413. }
  2414. Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
  2415. //parse methods
  2416. bool has_ready = false;
  2417. for (int i = 0; i < p_class->members.size(); i++) {
  2418. const GDScriptParser::ClassNode::Member &member = p_class->members[i];
  2419. if (member.type == member.FUNCTION) {
  2420. const GDScriptParser::FunctionNode *function = member.function;
  2421. if (!has_ready && function->identifier->name == "_ready") {
  2422. has_ready = true;
  2423. }
  2424. Error err = _parse_function(p_script, p_class, function);
  2425. if (err) {
  2426. return err;
  2427. }
  2428. } else if (member.type == member.VARIABLE) {
  2429. const GDScriptParser::VariableNode *variable = member.variable;
  2430. if (variable->property == GDScriptParser::VariableNode::PROP_INLINE) {
  2431. if (variable->setter != nullptr) {
  2432. Error err = _parse_setter_getter(p_script, p_class, variable, true);
  2433. if (err) {
  2434. return err;
  2435. }
  2436. }
  2437. if (variable->getter != nullptr) {
  2438. Error err = _parse_setter_getter(p_script, p_class, variable, false);
  2439. if (err) {
  2440. return err;
  2441. }
  2442. }
  2443. }
  2444. }
  2445. }
  2446. {
  2447. // Create an implicit constructor in any case.
  2448. Error err = _parse_function(p_script, p_class, nullptr);
  2449. if (err) {
  2450. return err;
  2451. }
  2452. }
  2453. if (!has_ready && p_class->onready_used) {
  2454. //create a _ready constructor
  2455. Error err = _parse_function(p_script, p_class, nullptr, true);
  2456. if (err) {
  2457. return err;
  2458. }
  2459. }
  2460. #ifdef DEBUG_ENABLED
  2461. //validate instances if keeping state
  2462. if (p_keep_state) {
  2463. for (Set<Object *>::Element *E = p_script->instances.front(); E;) {
  2464. Set<Object *>::Element *N = E->next();
  2465. ScriptInstance *si = E->get()->get_script_instance();
  2466. if (si->is_placeholder()) {
  2467. #ifdef TOOLS_ENABLED
  2468. PlaceHolderScriptInstance *psi = static_cast<PlaceHolderScriptInstance *>(si);
  2469. if (p_script->is_tool()) {
  2470. //re-create as an instance
  2471. p_script->placeholders.erase(psi); //remove placeholder
  2472. GDScriptInstance *instance = memnew(GDScriptInstance);
  2473. instance->base_ref = Object::cast_to<Reference>(E->get());
  2474. instance->members.resize(p_script->member_indices.size());
  2475. instance->script = Ref<GDScript>(p_script);
  2476. instance->owner = E->get();
  2477. //needed for hot reloading
  2478. for (Map<StringName, GDScript::MemberInfo>::Element *F = p_script->member_indices.front(); F; F = F->next()) {
  2479. instance->member_indices_cache[F->key()] = F->get().index;
  2480. }
  2481. instance->owner->set_script_instance(instance);
  2482. /* STEP 2, INITIALIZE AND CONSTRUCT */
  2483. Callable::CallError ce;
  2484. p_script->initializer->call(instance, nullptr, 0, ce);
  2485. if (ce.error != Callable::CallError::CALL_OK) {
  2486. //well, tough luck, not goinna do anything here
  2487. }
  2488. }
  2489. #endif
  2490. } else {
  2491. GDScriptInstance *gi = static_cast<GDScriptInstance *>(si);
  2492. gi->reload_members();
  2493. }
  2494. E = N;
  2495. }
  2496. }
  2497. #endif
  2498. for (int i = 0; i < p_class->members.size(); i++) {
  2499. if (p_class->members[i].type != GDScriptParser::ClassNode::Member::CLASS) {
  2500. continue;
  2501. }
  2502. const GDScriptParser::ClassNode *inner_class = p_class->members[i].m_class;
  2503. StringName name = inner_class->identifier->name;
  2504. GDScript *subclass = p_script->subclasses[name].ptr();
  2505. Error err = _parse_class_blocks(subclass, inner_class, p_keep_state);
  2506. if (err) {
  2507. return err;
  2508. }
  2509. }
  2510. p_script->valid = true;
  2511. return OK;
  2512. }
  2513. void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
  2514. Map<StringName, Ref<GDScript>> old_subclasses;
  2515. if (p_keep_state) {
  2516. old_subclasses = p_script->subclasses;
  2517. }
  2518. p_script->subclasses.clear();
  2519. for (int i = 0; i < p_class->members.size(); i++) {
  2520. if (p_class->members[i].type != GDScriptParser::ClassNode::Member::CLASS) {
  2521. continue;
  2522. }
  2523. const GDScriptParser::ClassNode *inner_class = p_class->members[i].m_class;
  2524. StringName name = inner_class->identifier->name;
  2525. Ref<GDScript> subclass;
  2526. String fully_qualified_name = p_script->fully_qualified_name + "::" + name;
  2527. if (old_subclasses.has(name)) {
  2528. subclass = old_subclasses[name];
  2529. } else {
  2530. Ref<GDScript> orphan_subclass = GDScriptLanguage::get_singleton()->get_orphan_subclass(fully_qualified_name);
  2531. if (orphan_subclass.is_valid()) {
  2532. subclass = orphan_subclass;
  2533. } else {
  2534. subclass.instance();
  2535. }
  2536. }
  2537. subclass->_owner = p_script;
  2538. subclass->fully_qualified_name = fully_qualified_name;
  2539. p_script->subclasses.insert(name, subclass);
  2540. _make_scripts(subclass.ptr(), inner_class, false);
  2541. }
  2542. }
  2543. Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state) {
  2544. err_line = -1;
  2545. err_column = -1;
  2546. error = "";
  2547. parser = p_parser;
  2548. main_script = p_script;
  2549. const GDScriptParser::ClassNode *root = parser->get_tree();
  2550. source = p_script->get_path();
  2551. // The best fully qualified name for a base level script is its file path
  2552. p_script->fully_qualified_name = p_script->path;
  2553. // Create scripts for subclasses beforehand so they can be referenced
  2554. _make_scripts(p_script, root, p_keep_state);
  2555. p_script->_owner = nullptr;
  2556. Error err = _parse_class_level(p_script, root, p_keep_state);
  2557. if (err) {
  2558. return err;
  2559. }
  2560. err = _parse_class_blocks(p_script, root, p_keep_state);
  2561. if (err) {
  2562. return err;
  2563. }
  2564. return GDScriptCache::finish_compiling(p_script->get_path());
  2565. }
  2566. String GDScriptCompiler::get_error() const {
  2567. return error;
  2568. }
  2569. int GDScriptCompiler::get_error_line() const {
  2570. return err_line;
  2571. }
  2572. int GDScriptCompiler::get_error_column() const {
  2573. return err_column;
  2574. }
  2575. GDScriptCompiler::GDScriptCompiler() {
  2576. }