gdscript_compiler.cpp 108 KB

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