From 30946b5cf382779844001241bb03d7419ebd5328 Mon Sep 17 00:00:00 2001 From: bear_369 <98942034+bearU369@users.noreply.github.com> Date: Sun, 22 Feb 2026 17:12:53 +0800 Subject: [PATCH] Add GlobalBeginFunctionInstruction for 'globals' - Some issue with JassProgram::initialize causes global variables to re-register already-defined variables, eliminating their values that would cause NullPointerException error. - Until a better solution for handling GlobalAssignmentInstruction instructions stored in `globals` is found, this function is made to skip the thread's instructionPtr to return address if the global variables are already initialized. --- .../GlobalBeginFunctionInstruction.java | 21 +++++++++++++++++++ .../interpreter/ast/scope/GlobalScope.java | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 jassparser/src/com/etheller/interpreter/ast/execution/instruction/GlobalBeginFunctionInstruction.java diff --git a/jassparser/src/com/etheller/interpreter/ast/execution/instruction/GlobalBeginFunctionInstruction.java b/jassparser/src/com/etheller/interpreter/ast/execution/instruction/GlobalBeginFunctionInstruction.java new file mode 100644 index 000000000..029d6d079 --- /dev/null +++ b/jassparser/src/com/etheller/interpreter/ast/execution/instruction/GlobalBeginFunctionInstruction.java @@ -0,0 +1,21 @@ +package com.etheller.interpreter.ast.execution.instruction; + +import com.etheller.interpreter.ast.execution.JassThread; + +public class GlobalBeginFunctionInstruction extends BeginFunctionInstruction { + private boolean isDefined = false; // Prevent from multiple JassProgram::initialize calls to re-register the already defined global variables. + + public GlobalBeginFunctionInstruction(final int lineNo, final String sourceFile, final String name) { + super(lineNo, sourceFile, name); + } + + @Override + public void run(JassThread thread) { + super.run(thread); + if (isDefined) { + thread.instructionPtr = thread.stackFrame.returnAddressInstructionPtr; + return; + } + isDefined = true; + } +} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java b/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java index 93ddb8dcb..97a8f327e 100644 --- a/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java +++ b/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java @@ -21,6 +21,7 @@ import com.etheller.interpreter.ast.execution.JassThread; import com.etheller.interpreter.ast.execution.instruction.BeginFunctionInstruction; import com.etheller.interpreter.ast.execution.instruction.BranchInstruction; +import com.etheller.interpreter.ast.execution.instruction.GlobalBeginFunctionInstruction; import com.etheller.interpreter.ast.execution.instruction.InstructionAppendingJassStatementVisitor; import com.etheller.interpreter.ast.execution.instruction.JassInstruction; import com.etheller.interpreter.ast.execution.instruction.PushLiteralInstruction; @@ -384,7 +385,7 @@ public void innerBeginDefiningGlobals(final int lineNo, final String sourceFile) else { this.functionNameToInstructionPtr.put(INIT_GLOBALS_AUTOGEN_FXN_NAME, this.instructions.size()); } - this.instructions.add(new BeginFunctionInstruction(lineNo, sourceFile, INIT_GLOBALS_AUTOGEN_FXN_NAME)); + this.instructions.add(new GlobalBeginFunctionInstruction(lineNo, sourceFile, INIT_GLOBALS_AUTOGEN_FXN_NAME)); } public UserJassFunction getFunctionDefinitionByName(final String name) {