Skip to content

Commit

Permalink
fix cw compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed May 5, 2024
1 parent bfb5ce4 commit 1b97ded
Show file tree
Hide file tree
Showing 10 changed files with 943 additions and 841 deletions.
2 changes: 1 addition & 1 deletion grammar/gsc.g4
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace: '#namespace' IDENTIFIER ';';
function
: ('function')?
('private')?
('autoexec')?
('autoexec' ('(' number ')')?)?
('event_handler' '[' IDENTIFIER ']')?
IDENTIFIER '(' param_list ')' statement_block;

Expand Down
223 changes: 111 additions & 112 deletions src/acts/compiler/gscLexer.cpp

Large diffs are not rendered by default.

1,379 changes: 698 additions & 681 deletions src/acts/compiler/gscParser.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/acts/compiler/gscParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class gscParser : public antlr4::Parser {
antlr4::tree::TerminalNode* IDENTIFIER(size_t i);
Param_listContext *param_list();
Statement_blockContext *statement_block();
NumberContext *number();


virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
Expand Down
94 changes: 71 additions & 23 deletions src/acts/compiler/gsc_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,13 @@ enum FuncCallFlags {

class AscmNodeFunctionCall : public AscmNodeOpCode {
public:
uint64_t nameSpace;
uint64_t clsName;
int flags;
byte params;

AscmNodeFunctionCall(OPCode opcode, int flags, byte params, uint64_t clsName) : AscmNodeOpCode(opcode), flags(flags), params(params), clsName(clsName) {
AscmNodeFunctionCall(OPCode opcode, int flags, byte params, uint64_t clsName, uint64_t nameSpace)
: AscmNodeOpCode(opcode), flags(flags), params(params), clsName(clsName), nameSpace(nameSpace) {
}

uint32_t ShiftSize(uint32_t start, bool aligned) const override {
Expand Down Expand Up @@ -211,7 +213,7 @@ class AscmNodeFunctionCall : public AscmNodeOpCode {
else if (!(flags & FCF_POINTER)) {
// replaced by the linker
ctx.Align<uint64_t>();
ctx.Write<uint64_t>(0x1234567887654321ull);
ctx.Write<uint64_t>(utils::CatLocated((uint32_t)nameSpace, (uint32_t)clsName));
}

return true;
Expand Down Expand Up @@ -443,8 +445,8 @@ class GscCompilerOption {
const char* m_outFileName{ "compiled"};
std::vector<const char*> m_inputFiles{};
bool m_client{};
uint64_t crcServer{};
uint64_t crcClient{};
int64_t crcServer{};
int64_t crcClient{};
const char* nameServer{ "" };
const char* nameClient{ "" };
PreProcessorOption processorOpt{};
Expand Down Expand Up @@ -509,7 +511,7 @@ class GscCompilerOption {
return false;
}
try {
crcServer = std::strtoull(args[++i], nullptr, 16);
crcServer = std::strtoll(args[++i], nullptr, 16);
}
catch (std::exception& e) {
LOG_ERROR("Invalid crc for {}: {} / {}!", arg, args[i], e.what());
Expand All @@ -522,7 +524,7 @@ class GscCompilerOption {
return false;
}
try {
crcClient = std::strtoull(args[++i], nullptr, 16);
crcClient = std::strtoll(args[++i], nullptr, 16);
}
catch (std::exception& e) {
LOG_ERROR("Invalid crc for {}: {} / {}!", arg, args[i], e.what());
Expand Down Expand Up @@ -668,6 +670,7 @@ struct FunctionJumpLoc {
class FunctionObject {
public:
CompileObject& obj;
int64_t autoexecOrder{};
uint64_t m_name;
uint64_t m_name_space;
uint64_t m_data_name;
Expand Down Expand Up @@ -805,6 +808,7 @@ class CompileObject {
std::unordered_map<std::string, GlobalVarObject> globals{};
VmInfo* vmInfo;
Platform plt;
int64_t autoexecOrder{};
std::shared_ptr<tool::gsc::GSCOBJHandler> gscHandler;
std::unordered_set<std::string> hashes{};

Expand Down Expand Up @@ -838,6 +842,7 @@ class CompileObject {
if (gscHandler->HasFlag(tool::gsc::GOHF_NOTIFY_CRC)) {
constexpr const char* name = "$notif_checkum";
uint64_t nameHashed = vmInfo->HashField(name);
hashes.insert(name);
auto [res, err] = exports.try_emplace(nameHashed, *this, nameHashed, currentNamespace, vmInfo);

if (!err) {
Expand All @@ -846,12 +851,12 @@ class CompileObject {
}

FunctionObject& f = res->second;
f.autoexecOrder = INT64_MIN; // first
f.m_flags = tool::gsc::CLASS_VTABLE;
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_CheckClearParams));
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_PreScriptCall));
f.m_nodes.push_back(BuildAscmNodeData(crc));


auto gvarIt = vmInfo->globalvars.find(vmInfo->HashField("level"));

if (gvarIt == vmInfo->globalvars.end()) {
Expand Down Expand Up @@ -898,7 +903,9 @@ class CompileObject {
LOG_TRACE("Compile {} export(s)...", exports.size());

size_t exportIndex{};
for (auto& [name, exp] : exports) {

auto& that = *this;
auto writeExport = [&data, &that, &expTable, &exportIndex](FunctionObject& exp) -> bool {
if (exp.m_nodes.empty()) {
LOG_ERROR("No nodes for {:x}", exp.m_name);
return false;
Expand All @@ -920,20 +927,55 @@ class CompileObject {
e.name = exp.m_name;
e.name_space = exp.m_name_space;
e.file_name_space = exp.m_data_name;
e.flags = gscHandler->MapFlagsExportToInt(exp.m_flags);
e.flags = that.gscHandler->MapFlagsExportToInt(exp.m_flags);
e.address = (int32_t)exp.location;
e.param_count = exp.m_params;
e.checksum = 0x12345678;
gscHandler->WriteExport(&data[expTable + gscHandler->GetExportSize() * exportIndex++], e);
that.gscHandler->WriteExport(&data[expTable + that.gscHandler->GetExportSize() * exportIndex++], e);

AscmCompilerContext cctx{ vmInfo, plt, exp.m_allocatedVar, data };
AscmCompilerContext cctx{ that.vmInfo, that.plt, exp.m_allocatedVar, data };

for (auto* node : exp.m_nodes) {
if (!node->Write(cctx)) {
return false;
}
}
return true;
};

std::vector<FunctionObject*> autoexecs{};

for (auto& [name, exp] : exports) {
if (exp.m_flags & tool::gsc::T8GSCExportFlags::AUTOEXEC) {
autoexecs.push_back(&exp);
}
}

// sort the autoexecs by ids and write them first

std::sort(autoexecs.begin(), autoexecs.end(), [](auto& f1, auto& f2) -> bool { return f1->autoexecOrder < f2->autoexecOrder; });

bool exportsOk{ true };
for (auto* exp : autoexecs) {
if (!writeExport(*exp)) {
exportsOk = false;
}
}

for (auto& [name, exp] : exports) {
if (exp.m_flags & tool::gsc::T8GSCExportFlags::AUTOEXEC) {
continue; // skip autoexecs
}

if (!writeExport(exp)) {
exportsOk = false;
}
}

if (!exportsOk) {
return false;
}

size_t csegSize = data.size() - csegOffset;

LOG_TRACE("Compile {} strings(s)...", strings.size());
Expand Down Expand Up @@ -1846,10 +1888,9 @@ bool ParseExpressionNode(ParseTree* exp, gscParser& parser, CompileObject& obj,
fobj.AddNode(arrVal, new AscmNodeVariable(arrayVal->id, OPCODE_EvalLocalVariableRefCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_SetVariableField));
// iterator = firstarray(array);
fobj.AddNode(arrVal, new AscmNodeVariable(arrayVal->id, OPCODE_EvalLocalVariableRefCached));
fobj.AddNode(arrVal, new AscmNodeVariable(arrayVal->id, OPCODE_EvalLocalVariableCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_FirstArrayKey));
fobj.AddNode(arrVal, new AscmNodeVariable(iteratorVal->id, OPCODE_EvalLocalVariableRefCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_SetVariableField));
fobj.AddNode(arrVal, new AscmNodeVariable(iteratorVal->id, OPCODE_SetLocalVariableCached));

AscmNode* loopBreak = new AscmNode();
AscmNode* loopContinue = new AscmNode();
Expand All @@ -1867,20 +1908,17 @@ bool ParseExpressionNode(ParseTree* exp, gscParser& parser, CompileObject& obj,
// key = iteratorkey(iterator);
fobj.AddNode(arrVal, new AscmNodeVariable(iteratorVal->id, OPCODE_EvalLocalVariableCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_T9_IteratorKey));
fobj.AddNode(arrVal, new AscmNodeVariable(keyVar->id, OPCODE_EvalLocalVariableRefCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_SetVariableField));
fobj.AddNode(arrVal, new AscmNodeVariable(keyVar->id, OPCODE_SetLocalVariableCached));

// val = iteratorval(iterator);
fobj.AddNode(arrVal, new AscmNodeVariable(iteratorVal->id, OPCODE_EvalLocalVariableCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_T9_IteratorVal));
fobj.AddNode(arrVal, new AscmNodeVariable(valueVar->id, OPCODE_EvalLocalVariableRefCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_SetVariableField));
fobj.AddNode(arrVal, new AscmNodeVariable(valueVar->id, OPCODE_SetLocalVariableCached));

// next = iteratornext(iterator);
fobj.AddNode(arrVal, new AscmNodeVariable(iteratorVal->id, OPCODE_EvalLocalVariableCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_T9_IteratorNext));
fobj.AddNode(arrVal, new AscmNodeVariable(nextVar->id, OPCODE_EvalLocalVariableRefCached));
fobj.AddNode(arrVal, new AscmNodeOpCode(OPCODE_SetVariableField));
fobj.AddNode(arrVal, new AscmNodeVariable(nextVar->id, OPCODE_SetLocalVariableCached));

if (!ParseExpressionNode(rule->children[rule->children.size() - 1], parser, obj, fobj, false)) {
ok = false;
Expand Down Expand Up @@ -2286,7 +2324,7 @@ bool ParseExpressionNode(ParseTree* exp, gscParser& parser, CompileObject& obj,
}
}
}
fobj.AddNode(rule, new AscmNodeFunctionCall(opcode, flags, (byte)paramCount, funcHash));
fobj.AddNode(rule, new AscmNodeFunctionCall(opcode, flags, (byte)paramCount, funcHash, funcNspHash));
}
else {
if (flags & FCF_METHOD) {
Expand Down Expand Up @@ -2318,7 +2356,7 @@ bool ParseExpressionNode(ParseTree* exp, gscParser& parser, CompileObject& obj,
}
}

auto* funcCall = new AscmNodeFunctionCall(opcode, flags, (byte)paramCount, funcHash);
auto* funcCall = new AscmNodeFunctionCall(opcode, flags, (byte)paramCount, funcHash, funcNspHash);

// link by the game, but we write it for test
Located located{ funcNspHash, funcHash };
Expand Down Expand Up @@ -2769,7 +2807,7 @@ bool ParseExpressionNode(ParseTree* exp, gscParser& parser, CompileObject& obj,

FunctionVar* var = fobj.FindVar(varName);

if (var) {
if (var != fobj.VarEnd()) {
fobj.AddNode(rule, new AscmNodeVariable(var->id, OPCODE_EvalLocalVariableRefCached));
fobj.AddNode(rule, new AscmNodeOpCode(OPCODE_T9_GetVarRef));
return true;
Expand Down Expand Up @@ -3237,6 +3275,16 @@ bool ParseFunction(gscParser::FunctionContext* func, gscParser& parser, CompileO
}
else if (txt == "autoexec") {
exp.m_flags |= tool::gsc::T8GSCExportFlags::AUTOEXEC;

if (IS_RULE_TYPE(func->children[i + 2], gscParser::RuleNumber)) {
// use user order
exp.autoexecOrder = NumberNodeValue(func->children[i + 2]);
i += 3;
}
else {
// use natural order
exp.autoexecOrder = obj.autoexecOrder++;
}
}
else if (txt == "event_handler") {
if (!obj.gscHandler->HasFlag(tool::gsc::GOHF_SUPPORT_EV_HANDLER)) {
Expand Down
6 changes: 3 additions & 3 deletions src/acts/tools/gsc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,7 @@ namespace tool::gsc {
virtual uint16_t GetGVarsCount() = 0;
virtual uint32_t GetGVarsOffset() = 0;
virtual uint32_t GetFileSize() = 0;
virtual uint64_t GetDefaultChecksum(bool client) = 0;
virtual int64_t GetDefaultChecksum(bool client) = 0;
virtual const char* GetDefaultName(bool client) = 0;

virtual size_t GetHeaderSize() = 0;
Expand Down Expand Up @@ -1083,8 +1083,8 @@ namespace tool::gsc {
T9_IF_FUNCTION_THREAD = 0x6,
T9_IF_METHOD = 0x7,
T9_IF_CALLTYPE_MASK = 0xF,
T9_IF_DEV_CALL = 0x10,
T9_IF_GET_CALL = 0x20,
T9_IF_GET_CALL = 0x10,
T9_IF_DEV_CALL = 0x20,
T9_IF_UKN40 = 0x40,
T9_IF_UKN80 = 0x80
};
Expand Down
23 changes: 14 additions & 9 deletions src/acts/tools/gsc_vm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,10 @@ class T8GSCOBJHandler : public GSCOBJHandler {
}
void WriteAnimTreeSingle(byte* data, const tool::gsc::GSC_USEANIMTREE_ITEM& item) override { }
void WriteAnimTreeDouble(byte* data, const tool::gsc::GSC_ANIMTREE_ITEM& item) override { }
uint64_t GetDefaultChecksum(bool client) override {
int64_t GetDefaultChecksum(bool client) override {
// todo: check client
return 0x636e9d38;
constexpr int32_t t = 0x636e9d38;
return t;
}
void SetChecksum(uint64_t val) override {
Ptr<T8GSCOBJ>()->crc = (uint32_t)val;
Expand Down Expand Up @@ -434,9 +435,10 @@ class T937GSCOBJHandler : public GSCOBJHandler {
}
void WriteAnimTreeSingle(byte* data, const tool::gsc::GSC_USEANIMTREE_ITEM& item) override { }
void WriteAnimTreeDouble(byte* data, const tool::gsc::GSC_ANIMTREE_ITEM& item) override { }
uint64_t GetDefaultChecksum(bool client) override {
int64_t GetDefaultChecksum(bool client) override {
// todo: check client
return 0xefc1b08d;
constexpr int32_t t = 0xefc1b08d;
return t;
}
void SetChecksum(uint64_t val) override {
Ptr<T937GSCOBJ>()->crc = (uint32_t)val;
Expand Down Expand Up @@ -547,7 +549,8 @@ class T9GSCOBJHandler : public GSCOBJHandler {
default: nflags |= flags & 0xF; // wtf?
}

nflags |= flags & ~T9_IF_CALLTYPE_MASK;
if (flags & T9_IF_DEV_CALL) nflags |= DEV_CALL;
if (flags & T9_IF_GET_CALL) nflags |= GET_CALL;

return nflags;
}
Expand Down Expand Up @@ -584,7 +587,8 @@ class T9GSCOBJHandler : public GSCOBJHandler {
default: nflags |= flags & 0xF; // wtf?
}

nflags |= flags & ~T9_IF_CALLTYPE_MASK;
if (flags & DEV_CALL) nflags |= T9_IF_DEV_CALL;
if (flags & GET_CALL) nflags |= T9_IF_GET_CALL;

return nflags;
}
Expand Down Expand Up @@ -713,9 +717,10 @@ class T9GSCOBJHandler : public GSCOBJHandler {
}
void WriteAnimTreeSingle(byte* data, const tool::gsc::GSC_USEANIMTREE_ITEM& item) override { }
void WriteAnimTreeDouble(byte* data, const tool::gsc::GSC_ANIMTREE_ITEM& item) override { }
uint64_t GetDefaultChecksum(bool client) override {
int64_t GetDefaultChecksum(bool client) override {
// todo: check client
return 0xc97916a2;
constexpr int32_t t = 0xc97916a2;
return t;
}
void SetChecksum(uint64_t val) override {
Ptr<T9GSCOBJ>()->crc = (uint32_t)val;
Expand Down Expand Up @@ -1016,7 +1021,7 @@ class MW23GSCOBJHandler : public GSCOBJHandler {
void WriteAnimTreeDouble(byte* data, const tool::gsc::GSC_ANIMTREE_ITEM& item) override {
*reinterpret_cast<tool::gsc::GSC_ANIMTREE_ITEM*>(data) = item;
}
uint64_t GetDefaultChecksum(bool client) override {
int64_t GetDefaultChecksum(bool client) override {
return 0; // no checksum
}
void SetChecksum(uint64_t val) override { }
Expand Down
1 change: 1 addition & 0 deletions test/gsc-compiler/acts.gsc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function on_player_connect() {
i = 0;
test:
i++;
self.score = 20000;
level.acts.counter++;
if (self usebuttonpressed()) {

Expand Down
Loading

0 comments on commit 1b97ded

Please sign in to comment.