Try getting a registered variable from the current script's global memory, or local memory (stack); or, if this is an imported variable, then lookup the import table for its real address.
| 471 | // or local memory (stack); or, if this is an imported variable, then lookup |
| 472 | // the import table for its real address. |
| 473 | static HError ParseScriptVariable(const String &field_ref, const ScriptExecutor *exec, |
| 474 | const RTTI &rtti, MemoryReference &mem_ref, FieldInfo &next_field_info) |
| 475 | { |
| 476 | MemoryVariable memvar; |
| 477 | // First try local data |
| 478 | if (!TryGetLocalVariable(field_ref, exec, memvar)) |
| 479 | { |
| 480 | // Then try script's global variable; |
| 481 | // this includes imported symbols from other scripts, plugins or engine |
| 482 | if (!TryGetGlobalVariable(field_ref, exec, memvar)) |
| 483 | { |
| 484 | return new Error(String::FromFormat("Variable not found in the current scope: '%s'", field_ref.GetCStr())); |
| 485 | } |
| 486 | } |
| 487 | |
| 488 | // Add found variable to the instruction list |
| 489 | const auto &var = *memvar.Variable; |
| 490 | // resolve local script's type to a global type index |
| 491 | // TODO: this should be resolved after loading script, similar to RTTI! |
| 492 | const RuntimeScript *top_inst = exec->GetRunningScript(); |
| 493 | const auto *l2gtypes = &top_inst->GetLocal2GlobalTypeMap(); |
| 494 | auto type_it = l2gtypes->find(var.f_typeid); |
| 495 | if (type_it == l2gtypes->end()) |
| 496 | return new Error(String::FromFormat("Type info not found for variable: '%s'", field_ref.GetCStr())); |
| 497 | uint32_t g_typeid = type_it->second; |
| 498 | const RTTI::Type &field_type = rtti.GetTypes()[g_typeid]; |
| 499 | WriteMemReadInstruction(mem_ref.Instruction, field_type, var.f_flags, var.num_elems, true, 0u); |
| 500 | mem_ref.MemPtr = memvar.MemoryPtr; |
| 501 | mem_ref.ObjMgr = memvar.ObjMgr; |
| 502 | mem_ref.MemSize = memvar.MemorySize; |
| 503 | next_field_info = FieldInfo(&field_type, var.f_flags, var.num_elems); |
| 504 | return HError::None(); |
| 505 | } |
| 506 | |
| 507 | // Parses a field name of a given type, writes memory read instruction into "mem_ref", |
| 508 | // assigns the found field's type into provided "field_type". |
no test coverage detected