// Copyright 2024 xensik. All rights reserved. // // Use of this source code is governed by a GNU GPLv3 license // that can be found in the LICENSE file. #include "xsk/stdinc.hpp" #include "xsk/gsc/context.hpp" namespace xsk::gsc { extern std::array, opcode_count> const opcode_list; context::context(gsc::props props, gsc::engine engine, gsc::endian endian, gsc::system system, u32 str_count) : props_{ props }, engine_{ engine }, endian_{ endian }, system_{ system }, instance_{ gsc::instance::server }, str_count_{ str_count }, source_{ this }, assembler_{ this }, disassembler_{ this }, compiler_{ this }, decompiler_{ this } { opcode_map_.reserve(opcode_list.size()); opcode_map_rev_.reserve(opcode_list.size()); for (auto const& entry : opcode_list) { opcode_map_.insert({ entry.first, entry.second }); opcode_map_rev_.insert({ entry.second, entry.first }); } } auto context::init(gsc::build build, fs_callback callback) -> void { build_ = build; fs_callback_ = callback; } auto context::cleanup() -> void { header_files_.clear(); include_cache_.clear(); includes_.clear(); } auto context::engine_name() const -> std::string_view { switch (engine_) { case engine::iw5: return "IW5"; case engine::iw6: return "IW6"; case engine::iw7: return "IW7"; case engine::iw8: return "IW8"; case engine::iw9: return "IW9"; case engine::s1: return "S1"; case engine::s2: return "S2"; case engine::s4: return "S4"; case engine::h1: return "H1"; case engine::h2: return "H2"; } return ""; } auto context::opcode_size(opcode op) const -> u32 { switch (op) { case opcode::OP_CastFieldObject: case opcode::OP_plus: case opcode::OP_GetGameRef: case opcode::OP_GetThisthread: case opcode::OP_greater: case opcode::OP_shift_right: case opcode::OP_dec: case opcode::OP_bit_or: case opcode::OP_equality: case opcode::OP_ClearLocalVariableFieldCached0: case opcode::OP_notify: case opcode::OP_PreScriptCall: case opcode::OP_GetUndefined: case opcode::OP_SetLocalVariableFieldCached0: case opcode::OP_GetLevel: case opcode::OP_size: case opcode::OP_AddArray: case opcode::OP_endon: case opcode::OP_shift_left: case opcode::OP_EvalLocalArrayRefCached0: case opcode::OP_Return: case opcode::OP_SafeSetVariableFieldCached0: case opcode::OP_GetSelfObject: case opcode::OP_GetGame: case opcode::OP_EvalArray: case opcode::OP_GetSelf: case opcode::OP_End: case opcode::OP_less_equal: case opcode::OP_EvalLocalVariableCached0: case opcode::OP_EvalLocalVariableCached1: case opcode::OP_EvalLocalVariableCached2: case opcode::OP_EvalLocalVariableCached3: case opcode::OP_EvalLocalVariableCached4: case opcode::OP_EvalLocalVariableCached5: case opcode::OP_ScriptMethodCallPointer: case opcode::OP_checkclearparams: case opcode::OP_waittillmatch2: case opcode::OP_minus: case opcode::OP_greater_equal: case opcode::OP_vector: case opcode::OP_ClearArray: case opcode::OP_DecTop: case opcode::OP_CastBool: case opcode::OP_EvalArrayRef: case opcode::OP_GetZero: case opcode::OP_wait: case opcode::OP_waittill: case opcode::OP_GetAnimObject: case opcode::OP_mod: case opcode::OP_clearparams: case opcode::OP_ScriptFunctionCallPointer: case opcode::OP_EmptyArray: case opcode::OP_BoolComplement: case opcode::OP_less: case opcode::OP_BoolNot: case opcode::OP_waittillFrameEnd: case opcode::OP_waitframe: case opcode::OP_GetLevelObject: case opcode::OP_inc: case opcode::OP_GetAnim: case opcode::OP_SetVariableField: case opcode::OP_divide: case opcode::OP_multiply: case opcode::OP_EvalLocalVariableRefCached0: case opcode::OP_bit_and: case opcode::OP_voidCodepos: case opcode::OP_inequality: case opcode::OP_bit_ex_or: case opcode::OP_BoolNotAfterAnd: case opcode::OP_IsDefined: case opcode::OP_IsTrue: return 1; case opcode::OP_SetLocalVariableFieldCached: case opcode::OP_RemoveLocalVariables: case opcode::OP_waittillmatch: case opcode::OP_ScriptMethodChildThreadCallPointer: case opcode::OP_GetByte: case opcode::OP_SafeSetWaittillVariableFieldCached: case opcode::OP_CallBuiltinMethodPointer: case opcode::OP_EvalLocalVariableCached: case opcode::OP_ScriptChildThreadCallPointer: case opcode::OP_EvalLocalVariableObjectCached: case opcode::OP_GetNegByte: case opcode::OP_GetAnimTree: case opcode::OP_EvalLocalArrayCached: case opcode::OP_ScriptMethodThreadCallPointer: case opcode::OP_SafeSetVariableFieldCached: case opcode::OP_EvalLocalVariableRefCached: case opcode::OP_ScriptThreadCallPointer: case opcode::OP_ClearLocalVariableFieldCached: case opcode::OP_EvalLocalArrayRefCached: case opcode::OP_CallBuiltinPointer: case opcode::OP_FormalParams: return 2; case opcode::OP_JumpOnTrue: case opcode::OP_JumpOnFalseExpr: case opcode::OP_jumpback: case opcode::OP_JumpOnTrueExpr: case opcode::OP_CallBuiltin0: case opcode::OP_CallBuiltin1: case opcode::OP_CallBuiltin2: case opcode::OP_CallBuiltin3: case opcode::OP_CallBuiltin4: case opcode::OP_CallBuiltin5: case opcode::OP_GetBuiltinFunction: case opcode::OP_GetNegUnsignedShort: case opcode::OP_GetBuiltinMethod: case opcode::OP_endswitch: case opcode::OP_GetUnsignedShort: case opcode::OP_JumpOnFalse: case opcode::OP_CallBuiltinMethod0: case opcode::OP_CallBuiltinMethod1: case opcode::OP_CallBuiltinMethod2: case opcode::OP_CallBuiltinMethod3: case opcode::OP_CallBuiltinMethod4: case opcode::OP_CallBuiltinMethod5: return 3; case opcode::OP_CallBuiltin: case opcode::OP_ScriptLocalMethodCall: case opcode::OP_ScriptLocalFunctionCall2: case opcode::OP_ScriptFarFunctionCall2: case opcode::OP_CallBuiltinMethod: case opcode::OP_GetLocalFunction: case opcode::OP_ScriptLocalFunctionCall: return 4; case opcode::OP_ScriptLocalMethodThreadCall: case opcode::OP_ScriptLocalChildThreadCall: case opcode::OP_ScriptLocalThreadCall: case opcode::OP_GetInteger: case opcode::OP_ScriptLocalMethodChildThreadCall: case opcode::OP_GetFloat: case opcode::OP_switch: case opcode::OP_jump: case opcode::OP_GetUnkxHash: case opcode::OP_GetUnsignedInt: case opcode::OP_GetNegUnsignedInt: return 5; case opcode::OP_GetStatHash: case opcode::OP_GetEnumHash: case opcode::OP_GetDvarHash: case opcode::OP_GetInteger64: return 9; case opcode::OP_GetFarFunction: case opcode::OP_ScriptFarFunctionCall: case opcode::OP_ScriptFarMethodCall: return (props_ & props::farcall) ? 5 : 4; case opcode::OP_ScriptFarThreadCall: case opcode::OP_ScriptFarChildThreadCall: case opcode::OP_ScriptFarMethodThreadCall: case opcode::OP_ScriptFarMethodChildThreadCall: return (props_ & props::farcall) ? 6 : 5; case opcode::OP_CreateLocalVariable: case opcode::OP_EvalNewLocalArrayRefCached0: case opcode::OP_SafeCreateVariableFieldCached: case opcode::OP_SetNewLocalVariableFieldCached0: return (props_ & props::hash) ? 9 : 2; case opcode::OP_EvalSelfFieldVariableRef: case opcode::OP_EvalAnimFieldVariable: case opcode::OP_EvalLevelFieldVariableRef: case opcode::OP_SetSelfFieldVariableField: case opcode::OP_ClearFieldVariable: case opcode::OP_EvalFieldVariable: case opcode::OP_SetAnimFieldVariableField: case opcode::OP_SetLevelFieldVariableField: case opcode::OP_EvalSelfFieldVariable: case opcode::OP_EvalFieldVariableRef: case opcode::OP_EvalLevelFieldVariable: case opcode::OP_EvalAnimFieldVariableRef: return (props_ & props::hash) ? 9 : (props_ & props::tok4) ? 5 : 3; case opcode::OP_GetString: case opcode::OP_GetIString: return (props_ & props::str4) ? 5 : 3; case opcode::OP_GetAnimation: return (props_ & props::str4) ? 9 : 5; case opcode::OP_GetVector: return 13; case opcode::OP_ClearVariableField: case opcode::OP_EvalNewLocalVariableRefCached0: case opcode::OP_NOP: case opcode::OP_abort: case opcode::OP_object: case opcode::OP_thread_object: case opcode::OP_EvalLocalVariable: case opcode::OP_EvalLocalVariableRef: case opcode::OP_breakpoint: case opcode::OP_assignmentBreakpoint: case opcode::OP_manualAndAssignmentBreakpoint: case opcode::OP_prof_begin: case opcode::OP_prof_end: case opcode::OP_NativeGetLocalFunction: case opcode::OP_NativeLocalFunctionCall: case opcode::OP_NativeLocalFunctionCall2: case opcode::OP_NativeLocalMethodCall: case opcode::OP_NativeGetFarFunction: case opcode::OP_NativeFarFunctionCall: case opcode::OP_NativeFarFunctionCall2: case opcode::OP_NativeFarMethodCall: case opcode::OP_NativeLocalFunctionThreadCall: case opcode::OP_NativeLocalMethodThreadCall: case opcode::OP_NativeLocalFunctionChildThreadCall: case opcode::OP_NativeLocalMethodChildThreadCall: case opcode::OP_NativeFarFunctionThreadCall: case opcode::OP_NativeFarMethodThreadCall: case opcode::OP_NativeFarFunctionChildThreadCall: case opcode::OP_NativeFarMethodChildThreadCall: case opcode::OP_EvalNewLocalArrayRefCached0_Precompiled: case opcode::OP_SetNewLocalVariableFieldCached0_Precompiled: case opcode::OP_CreateLocalVariable_Precompiled: case opcode::OP_SafeCreateVariableFieldCached_Precompiled: case opcode::OP_FormalParams_Precompiled: case opcode::OP_iw9_139: case opcode::OP_iw9_140: case opcode::OP_iw9_141: case opcode::OP_iw9_142: case opcode::OP_iw9_143: case opcode::OP_iw9_144: case opcode::OP_iw9_166: default: throw error(std::format("couldn't resolve instruction size for '{}'", opcode_name(op))); } } auto context::opcode_id(opcode op) const -> u8 { auto const itr = code_map_rev_.find(op); if (itr != code_map_rev_.end()) { return itr->second; } throw error(std::format("couldn't resolve opcode id for '{}'", opcode_name(op))); } auto context::opcode_name(opcode op) const -> std::string { auto const itr = opcode_map_.find(op); if (itr != opcode_map_.end()) { return std::string{ itr->second }; } throw std::runtime_error(std::format("couldn't resolve opcode string for enum '{}'", static_cast>(op))); } auto context::opcode_enum(std::string const& name) const -> opcode { auto const itr = opcode_map_rev_.find(name); if (itr != opcode_map_rev_.end()) { return itr->second; } throw std::runtime_error(std::format("couldn't resolve opcode enum for name '{}'", name)); } auto context::opcode_enum(u8 id) const -> opcode { auto const itr = code_map_.find(id); if (itr != code_map_.end()) { return itr->second; } throw error(std::format("couldn't resolve opcode enum for '{:02X}'", id)); } auto context::func_id(std::string const& name) const -> u16 { if (name.starts_with("_func_")) { return static_cast(std::stoul(name.substr(6), nullptr, 16)); } auto const itr = func_map_rev_.find(name); if (itr != func_map_rev_.end()) { return itr->second; } throw error(std::format("couldn't resolve builtin function id for {}", name)); } auto context::func_name(u16 id) const -> std::string { auto const itr = func_map_.find(id); if (itr != func_map_.end()) { return std::string{ itr->second }; } return std::format("_func_{:04X}", id); } auto context::func2_id(std::string const& name) const -> u64 { if (name.starts_with("_func_")) { return static_cast(std::stoull(name.substr(6), nullptr, 16)); } char const* str = name.data(); u64 hash = 0x79D6530B0BB9B5D1; while ( *str ) { u8 byte = *str++; if (static_cast(byte - 65) <= 25) { byte += 32; } hash = (u64)0x10000000233 * ((u64)byte ^ hash); } return hash; } auto context::func2_name(u64 id) const -> std::string { auto const itr = func_map2_.find(id); if (itr != func_map2_.end()) { return std::string{ itr->second }; } return std::format("_func_{:16X}", id); } auto context::func_exists(std::string const& name) const -> bool { if (name.starts_with("_func_")) return true; if (props_ & props::hash) { return func_map2_.contains(func2_id(name)); } else { return func_map_rev_.contains(name); } } auto context::func_add(std::string const& name, u16 id) -> void { auto const itr = func_map_rev_.find(name); if (itr != func_map_rev_.end()) { throw error(std::format("builtin function '{}' already defined", name)); } auto const str = new_func_map_.find(name); if (str != new_func_map_.end()) { func_map_.insert({ id, *str }); func_map_rev_.insert({ *str, id }); } else { auto ins = new_func_map_.insert(name); if (ins.second) { func_map_.insert({ id, *ins.first }); func_map_rev_.insert({ *ins.first, id }); } } } auto context::meth_id(std::string const& name) const -> u16 { if (name.starts_with("_meth_")) { return static_cast(std::stoul(name.substr(6), nullptr, 16)); } auto const itr = meth_map_rev_.find(name); if (itr != meth_map_rev_.end()) { return itr->second; } throw error(std::format("couldn't resolve builtin method id for {}", name)); } auto context::meth_name(u16 id) const -> std::string { auto const itr = meth_map_.find(id); if (itr != meth_map_.end()) { return std::string{ itr->second }; } return std::format("_meth_{:04X}", id); } auto context::meth2_id(std::string const& name) const -> u64 { if (name.starts_with("_meth_")) { return static_cast(std::stoull(name.substr(6), nullptr, 16)); } char const* str = name.data(); u64 hash = 0x79D6530B0BB9B5D1; while ( *str ) { u8 byte = *str++; if (static_cast(byte - 65) <= 25) { byte += 32; } hash = (u64)0x10000000233 * ((u64)byte ^ hash); } return hash; } auto context::meth2_name(u64 id) const -> std::string { auto const itr = meth_map2_.find(id); if (itr != meth_map2_.end()) { return std::string{ itr->second }; } return std::format("_meth_{:16X}", id); } auto context::meth_exists(std::string const& name) const -> bool { if (name.starts_with("_meth_")) return true; if (props_ & props::hash) { return meth_map2_.contains(meth2_id(name)); } else { return meth_map_rev_.contains(name); } } auto context::meth_add(std::string const& name, u16 id) -> void { auto const itr = meth_map_rev_.find(name); if (itr != meth_map_rev_.end()) { throw error(std::format("builtin method '{}' already defined", name)); } auto const str = new_meth_map_.find(name); if (str != new_meth_map_.end()) { meth_map_.insert({ id, *str }); meth_map_rev_.insert({ *str, id }); } else { auto ins = new_meth_map_.insert(name); if (ins.second) { meth_map_.insert({ id, *ins.first }); meth_map_rev_.insert({ *ins.first, id }); } } } auto context::token_id(std::string const& name) const -> u32 { if (name.starts_with("_id_")) { return static_cast(std::stoul(name.substr(4), nullptr, 16)); } auto const itr = token_map_rev_.find(name); if (itr != token_map_rev_.end()) { return itr->second; } return 0; } auto context::token_name(u32 id) const -> std::string { auto const itr = token_map_.find(id); if (itr != token_map_.end()) { return std::string{ itr->second }; } return std::format("_id_{:04X}", id); } auto context::path_id(std::string const& name) const -> u64 { if (name.starts_with("_id_")) { return static_cast(std::stoull(name.substr(4), nullptr, 16)); } char const* str = name.data(); u64 hash = 0x47F5817A5EF961BA; while ( *str ) { u8 byte = *str++; if (byte == '\\') { byte = '/'; } else if (static_cast(byte - 65) <= 25) { byte += 32; } hash = (u64)0x100000001B3 * ((u64)byte ^ hash); } return hash & 0x7FFFFFFFFFFFFFFF; } auto context::path_name(u64 id) const -> std::string { auto const itr = path_map_.find(id); if (itr != path_map_.end()) { return std::string{ itr->second }; } return std::format("_id_{:016X}", id); } auto context::hash_id(std::string const& name) const -> u64 { if (name.starts_with("_id_")) { return static_cast(std::stoull(name.substr(4), nullptr, 16)); } char const* str = name.data(); u64 hash = 0x79D6530B0BB9B5D1; while ( *str ) { u8 byte = *str++; if (static_cast(byte - 65) <= 25) { byte += 32; } hash = (u64)0x10000000233 * ((u64)byte ^ hash); } return hash; } auto context::hash_name(u64 id) const -> std::string { auto const itr = hash_map_.find(id); if (itr != hash_map_.end()) { return std::string{ itr->second }; } return std::format("_id_{:016X}", id); } auto context::make_token(std::string_view str) const -> std::string { if (str.starts_with("_id_") || str.starts_with("_func_") || str.starts_with("_meth_")) { return std::string{ str }; } auto data = std::string{ str.begin(), str.end() }; for (auto i = 0u; i < data.size(); i++) { data[i] = static_cast(std::tolower(static_cast(str[i]))); if (data[i] == '\\') data[i] = '/'; } return data; } auto context::load_header(std::string const& name) -> std::tuple { auto const itr = header_files_.find(name); if (itr != header_files_.end()) { return { &itr->first, reinterpret_cast(itr->second.data()), itr->second.size() }; } auto data = fs_callback_(this, name); if (data.first.data == nullptr && data.first.size == 0 && !data.second.empty()) { auto const res = header_files_.insert({ name, std::move(data.second) }); if (res.second) { return { &res.first->first, reinterpret_cast(res.first->second.data()), res.first->second.size() }; } } throw error(std::format("couldn't open gsh file '{}'", name)); } auto context::load_include(std::string const& name) -> bool { try { if (includes_.contains(name)) { return false; } includes_.insert(name); if (include_cache_.contains(name)) return true; auto filename = name; filename += (instance_ == gsc::instance::server) ? ".gsc" : ".csc"; auto file = fs_callback_(this, filename); if ((file.first.data == nullptr || file.first.size == 0) && file.second.empty()) throw std::runtime_error("empty file"); if (file.first.data == nullptr && file.first.size == 0 && !file.second.empty()) { // process RawFile auto prog = source_.parse_program(name, file.second); auto funcs = std::vector{}; for (auto const& dec : prog->declarations) { if (dec->is()) { funcs.push_back(dec->as().name->value); } } include_cache_.insert({ name, std::move(funcs) }); } else { // process ScriptFile auto data = disassembler_.disassemble(file.first, buffer{ file.second.data(), file.second.size() }); auto funcs = std::vector{}; for (auto const& fun : data->functions) { funcs.push_back(fun->name); } include_cache_.insert({ name, std::move(funcs) }); } return true; } catch (std::exception const& e) { throw error(std::format("parsing include file '{}': {}", name, e.what())); } } auto context::init_includes() -> void { includes_.clear(); } auto context::is_includecall(std::string const& name, std::string& path) -> bool { for (auto const& inc : includes_) { for (auto const& fun : include_cache_.at(std::string{ inc })) { if (name == fun) { path = inc; return true; } } } return false; } extern std::array, opcode_count> const opcode_list {{ { opcode::vm_invalid, "vm_invalid" }, { opcode::OP_CastFieldObject, "OP_CastFieldObject" }, { opcode::OP_SetLocalVariableFieldCached, "OP_SetLocalVariableFieldCached" }, { opcode::OP_plus, "OP_plus" }, { opcode::OP_RemoveLocalVariables, "OP_RemoveLocalVariables" }, { opcode::OP_EvalSelfFieldVariableRef, "OP_EvalSelfFieldVariableRef" }, { opcode::OP_ScriptFarMethodChildThreadCall, "OP_ScriptFarMethodChildThreadCall" }, { opcode::OP_GetGameRef, "OP_GetGameRef" }, { opcode::OP_EvalAnimFieldVariable, "OP_EvalAnimFieldVariable" }, { opcode::OP_EvalLevelFieldVariableRef, "OP_EvalLevelFieldVariableRef" }, { opcode::OP_GetThisthread, "OP_GetThisthread" }, { opcode::OP_greater, "OP_greater" }, { opcode::OP_waittillmatch, "OP_waittillmatch" }, { opcode::OP_shift_right, "OP_shift_right" }, { opcode::OP_dec, "OP_dec" }, { opcode::OP_JumpOnTrue, "OP_JumpOnTrue" }, { opcode::OP_bit_or, "OP_bit_or" }, { opcode::OP_equality, "OP_equality" }, { opcode::OP_ClearLocalVariableFieldCached0, "OP_ClearLocalVariableFieldCached0" }, { opcode::OP_notify, "OP_notify" }, { opcode::OP_GetVector, "OP_GetVector" }, { opcode::OP_ScriptMethodChildThreadCallPointer, "OP_ScriptMethodChildThreadCallPointer" }, { opcode::OP_PreScriptCall, "OP_PreScriptCall" }, { opcode::OP_GetByte, "OP_GetByte" }, { opcode::OP_ScriptFarThreadCall, "OP_ScriptFarThreadCall" }, { opcode::OP_SetSelfFieldVariableField, "OP_SetSelfFieldVariableField" }, { opcode::OP_JumpOnFalseExpr, "OP_JumpOnFalseExpr" }, { opcode::OP_GetUndefined, "OP_GetUndefined" }, { opcode::OP_jumpback, "OP_jumpback" }, { opcode::OP_JumpOnTrueExpr, "OP_JumpOnTrueExpr" }, { opcode::OP_CallBuiltin0, "OP_CallBuiltin0" }, { opcode::OP_CallBuiltin1, "OP_CallBuiltin1" }, { opcode::OP_CallBuiltin2, "OP_CallBuiltin2" }, { opcode::OP_CallBuiltin3, "OP_CallBuiltin3" }, { opcode::OP_CallBuiltin4, "OP_CallBuiltin4" }, { opcode::OP_CallBuiltin5, "OP_CallBuiltin5" }, { opcode::OP_CallBuiltin, "OP_CallBuiltin" }, { opcode::OP_SetLocalVariableFieldCached0, "OP_SetLocalVariableFieldCached0" }, { opcode::OP_ClearFieldVariable, "OP_ClearFieldVariable" }, { opcode::OP_GetLevel, "OP_GetLevel" }, { opcode::OP_size, "OP_size" }, { opcode::OP_SafeSetWaittillVariableFieldCached, "OP_SafeSetWaittillVariableFieldCached" }, { opcode::OP_ScriptLocalMethodThreadCall, "OP_ScriptLocalMethodThreadCall" }, { opcode::OP_AddArray, "OP_AddArray" }, { opcode::OP_endon, "OP_endon" }, { opcode::OP_EvalFieldVariable, "OP_EvalFieldVariable" }, { opcode::OP_shift_left, "OP_shift_left" }, { opcode::OP_EvalLocalArrayRefCached0, "OP_EvalLocalArrayRefCached0" }, { opcode::OP_Return, "OP_Return" }, { opcode::OP_CreateLocalVariable, "OP_CreateLocalVariable" }, { opcode::OP_SafeSetVariableFieldCached0, "OP_SafeSetVariableFieldCached0" }, { opcode::OP_GetBuiltinFunction, "OP_GetBuiltinFunction" }, { opcode::OP_ScriptLocalMethodCall, "OP_ScriptLocalMethodCall" }, { opcode::OP_CallBuiltinMethodPointer, "OP_CallBuiltinMethodPointer" }, { opcode::OP_ScriptLocalChildThreadCall, "OP_ScriptLocalChildThreadCall" }, { opcode::OP_GetSelfObject, "OP_GetSelfObject" }, { opcode::OP_GetGame, "OP_GetGame" }, { opcode::OP_SetLevelFieldVariableField, "OP_SetLevelFieldVariableField" }, { opcode::OP_EvalArray, "OP_EvalArray" }, { opcode::OP_GetSelf, "OP_GetSelf" }, { opcode::OP_End, "OP_End" }, { opcode::OP_EvalSelfFieldVariable, "OP_EvalSelfFieldVariable" }, { opcode::OP_less_equal, "OP_less_equal" }, { opcode::OP_EvalLocalVariableCached0, "OP_EvalLocalVariableCached0" }, { opcode::OP_EvalLocalVariableCached1, "OP_EvalLocalVariableCached1" }, { opcode::OP_EvalLocalVariableCached2, "OP_EvalLocalVariableCached2" }, { opcode::OP_EvalLocalVariableCached3, "OP_EvalLocalVariableCached3" }, { opcode::OP_EvalLocalVariableCached4, "OP_EvalLocalVariableCached4" }, { opcode::OP_EvalLocalVariableCached5, "OP_EvalLocalVariableCached5" }, { opcode::OP_EvalLocalVariableCached, "OP_EvalLocalVariableCached" }, { opcode::OP_EvalNewLocalArrayRefCached0, "OP_EvalNewLocalArrayRefCached0" }, { opcode::OP_ScriptChildThreadCallPointer, "OP_ScriptChildThreadCallPointer" }, { opcode::OP_EvalLocalVariableObjectCached, "OP_EvalLocalVariableObjectCached" }, { opcode::OP_ScriptLocalThreadCall, "OP_ScriptLocalThreadCall" }, { opcode::OP_GetInteger, "OP_GetInteger" }, { opcode::OP_ScriptMethodCallPointer, "OP_ScriptMethodCallPointer" }, { opcode::OP_checkclearparams, "OP_checkclearparams" }, { opcode::OP_SetAnimFieldVariableField, "OP_SetAnimFieldVariableField" }, { opcode::OP_waittillmatch2, "OP_waittillmatch2" }, { opcode::OP_minus, "OP_minus" }, { opcode::OP_ScriptLocalFunctionCall2, "OP_ScriptLocalFunctionCall2" }, { opcode::OP_GetNegUnsignedShort, "OP_GetNegUnsignedShort" }, { opcode::OP_GetNegByte, "OP_GetNegByte" }, { opcode::OP_SafeCreateVariableFieldCached, "OP_SafeCreateVariableFieldCached" }, { opcode::OP_greater_equal, "OP_greater_equal" }, { opcode::OP_vector, "OP_vector" }, { opcode::OP_GetBuiltinMethod, "OP_GetBuiltinMethod" }, { opcode::OP_endswitch, "OP_endswitch" }, { opcode::OP_ClearArray, "OP_ClearArray" }, { opcode::OP_DecTop, "OP_DecTop" }, { opcode::OP_CastBool, "OP_CastBool" }, { opcode::OP_EvalArrayRef, "OP_EvalArrayRef" }, { opcode::OP_SetNewLocalVariableFieldCached0, "OP_SetNewLocalVariableFieldCached0" }, { opcode::OP_GetZero, "OP_GetZero" }, { opcode::OP_wait, "OP_wait" }, { opcode::OP_waittill, "OP_waittill" }, { opcode::OP_GetIString, "OP_GetIString" }, { opcode::OP_ScriptFarFunctionCall, "OP_ScriptFarFunctionCall" }, { opcode::OP_GetAnimObject, "OP_GetAnimObject" }, { opcode::OP_GetAnimTree, "OP_GetAnimTree" }, { opcode::OP_EvalLocalArrayCached, "OP_EvalLocalArrayCached" }, { opcode::OP_mod, "OP_mod" }, { opcode::OP_ScriptFarMethodThreadCall, "OP_ScriptFarMethodThreadCall" }, { opcode::OP_GetUnsignedShort, "OP_GetUnsignedShort" }, { opcode::OP_clearparams, "OP_clearparams" }, { opcode::OP_ScriptMethodThreadCallPointer, "OP_ScriptMethodThreadCallPointer" }, { opcode::OP_ScriptFunctionCallPointer, "OP_ScriptFunctionCallPointer" }, { opcode::OP_EmptyArray, "OP_EmptyArray" }, { opcode::OP_SafeSetVariableFieldCached, "OP_SafeSetVariableFieldCached" }, { opcode::OP_ClearVariableField, "OP_ClearVariableField" }, { opcode::OP_EvalFieldVariableRef, "OP_EvalFieldVariableRef" }, { opcode::OP_ScriptLocalMethodChildThreadCall, "OP_ScriptLocalMethodChildThreadCall" }, { opcode::OP_EvalNewLocalVariableRefCached0, "OP_EvalNewLocalVariableRefCached0" }, { opcode::OP_GetFloat, "OP_GetFloat" }, { opcode::OP_EvalLocalVariableRefCached, "OP_EvalLocalVariableRefCached" }, { opcode::OP_JumpOnFalse, "OP_JumpOnFalse" }, { opcode::OP_BoolComplement, "OP_BoolComplement" }, { opcode::OP_ScriptThreadCallPointer, "OP_ScriptThreadCallPointer" }, { opcode::OP_ScriptFarFunctionCall2, "OP_ScriptFarFunctionCall2" }, { opcode::OP_less, "OP_less" }, { opcode::OP_BoolNot, "OP_BoolNot" }, { opcode::OP_waittillFrameEnd, "OP_waittillFrameEnd" }, { opcode::OP_waitframe, "OP_waitframe" }, { opcode::OP_GetString, "OP_GetString" }, { opcode::OP_EvalLevelFieldVariable, "OP_EvalLevelFieldVariable" }, { opcode::OP_GetLevelObject, "OP_GetLevelObject" }, { opcode::OP_inc, "OP_inc" }, { opcode::OP_CallBuiltinMethod0, "OP_CallBuiltinMethod0" }, { opcode::OP_CallBuiltinMethod1, "OP_CallBuiltinMethod1" }, { opcode::OP_CallBuiltinMethod2, "OP_CallBuiltinMethod2" }, { opcode::OP_CallBuiltinMethod3, "OP_CallBuiltinMethod3" }, { opcode::OP_CallBuiltinMethod4, "OP_CallBuiltinMethod4" }, { opcode::OP_CallBuiltinMethod5, "OP_CallBuiltinMethod5" }, { opcode::OP_CallBuiltinMethod, "OP_CallBuiltinMethod" }, { opcode::OP_GetAnim, "OP_GetAnim" }, { opcode::OP_switch, "OP_switch" }, { opcode::OP_SetVariableField, "OP_SetVariableField" }, { opcode::OP_divide, "OP_divide" }, { opcode::OP_GetLocalFunction, "OP_GetLocalFunction" }, { opcode::OP_ScriptFarChildThreadCall, "OP_ScriptFarChildThreadCall" }, { opcode::OP_multiply, "OP_multiply" }, { opcode::OP_ClearLocalVariableFieldCached, "OP_ClearLocalVariableFieldCached" }, { opcode::OP_EvalAnimFieldVariableRef, "OP_EvalAnimFieldVariableRef" }, { opcode::OP_EvalLocalArrayRefCached, "OP_EvalLocalArrayRefCached" }, { opcode::OP_EvalLocalVariableRefCached0, "OP_EvalLocalVariableRefCached0" }, { opcode::OP_bit_and, "OP_bit_and" }, { opcode::OP_GetAnimation, "OP_GetAnimation" }, { opcode::OP_GetFarFunction, "OP_GetFarFunction" }, { opcode::OP_CallBuiltinPointer, "OP_CallBuiltinPointer" }, { opcode::OP_jump, "OP_jump" }, { opcode::OP_voidCodepos, "OP_voidCodepos" }, { opcode::OP_ScriptFarMethodCall, "OP_ScriptFarMethodCall" }, { opcode::OP_inequality, "OP_inequality" }, { opcode::OP_ScriptLocalFunctionCall, "OP_ScriptLocalFunctionCall" }, { opcode::OP_bit_ex_or, "OP_bit_ex_or" }, { opcode::OP_NOP, "OP_NOP" }, { opcode::OP_abort, "OP_abort" }, { opcode::OP_object, "OP_object" }, { opcode::OP_thread_object, "OP_thread_object" }, { opcode::OP_EvalLocalVariable, "OP_EvalLocalVariable" }, { opcode::OP_EvalLocalVariableRef, "OP_EvalLocalVariableRef" }, { opcode::OP_prof_begin, "OP_prof_begin" }, { opcode::OP_prof_end, "OP_prof_end" }, { opcode::OP_breakpoint, "OP_breakpoint" }, { opcode::OP_assignmentBreakpoint, "OP_assignmentBreakpoint" }, { opcode::OP_manualAndAssignmentBreakpoint, "OP_manualAndAssignmentBreakpoint" }, { opcode::OP_BoolNotAfterAnd, "OP_BoolNotAfterAnd" }, { opcode::OP_FormalParams, "OP_FormalParams" }, { opcode::OP_IsDefined, "OP_IsDefined" }, { opcode::OP_IsTrue, "OP_IsTrue" }, { opcode::OP_NativeGetLocalFunction, "OP_NativeGetLocalFunction" }, { opcode::OP_NativeLocalFunctionCall, "OP_NativeLocalFunctionCall" }, { opcode::OP_NativeLocalFunctionCall2, "OP_NativeLocalFunctionCall2" }, { opcode::OP_NativeLocalMethodCall, "OP_NativeLocalMethodCall" }, { opcode::OP_NativeLocalFunctionThreadCall, "OP_NativeLocalFunctionThreadCall" }, { opcode::OP_NativeLocalMethodThreadCall, "OP_NativeLocalMethodThreadCall" }, { opcode::OP_NativeLocalFunctionChildThreadCall, "OP_NativeLocalFunctionChildThreadCall" }, { opcode::OP_NativeLocalMethodChildThreadCall, "OP_NativeLocalMethodChildThreadCall" }, { opcode::OP_NativeGetFarFunction, "OP_NativeGetFarFunction" }, { opcode::OP_NativeFarFunctionCall, "OP_NativeFarFunctionCall" }, { opcode::OP_NativeFarFunctionCall2, "OP_NativeFarFunctionCall2" }, { opcode::OP_NativeFarMethodCall, "OP_NativeFarMethodCall" }, { opcode::OP_NativeFarFunctionThreadCall, "OP_NativeFarFunctionThreadCall" }, { opcode::OP_NativeFarMethodThreadCall, "OP_NativeFarMethodThreadCall" }, { opcode::OP_NativeFarFunctionChildThreadCall, "OP_NativeFarFunctionChildThreadCall" }, { opcode::OP_NativeFarMethodChildThreadCall, "OP_NativeFarMethodChildThreadCall" }, { opcode::OP_EvalNewLocalArrayRefCached0_Precompiled, "OP_EvalNewLocalArrayRefCached0_Precompiled" }, { opcode::OP_SetNewLocalVariableFieldCached0_Precompiled, "OP_SetNewLocalVariableFieldCached0_Precompiled" }, { opcode::OP_CreateLocalVariable_Precompiled, "OP_CreateLocalVariable_Precompiled" }, { opcode::OP_SafeCreateVariableFieldCached_Precompiled, "OP_SafeCreateVariableFieldCached_Precompiled" }, { opcode::OP_FormalParams_Precompiled, "OP_FormalParams_Precompiled" }, { opcode::OP_GetStatHash, "OP_GetStatHash" }, { opcode::OP_GetUnkxHash, "OP_GetUnkxHash" }, { opcode::OP_GetEnumHash, "OP_GetEnumHash" }, { opcode::OP_GetDvarHash, "OP_GetDvarHash" }, { opcode::OP_GetUnsignedInt, "OP_GetUnsignedInt" }, { opcode::OP_GetNegUnsignedInt, "OP_GetNegUnsignedInt" }, { opcode::OP_GetInteger64, "OP_GetInteger64" }, { opcode::OP_iw9_139, "OP_iw9_139" }, { opcode::OP_iw9_140, "OP_iw9_140" }, { opcode::OP_iw9_141, "OP_iw9_141" }, { opcode::OP_iw9_142, "OP_iw9_142" }, { opcode::OP_iw9_143, "OP_iw9_143" }, { opcode::OP_iw9_144, "OP_iw9_144" }, { opcode::OP_iw9_166, "OP_iw9_166" }, }}; } // namespace xsk::gsc