Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDScript: Add support for relative paths in load() #90054

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions modules/gdscript/gdscript_byte_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,12 @@ void GDScriptByteCodeGenerator::write_assert(const Address &p_test, const Addres
append(p_message);
}

void GDScriptByteCodeGenerator::write_convert_relative_path(const Address &p_target, const Address &p_path) {
append_opcode(GDScriptFunction::OPCODE_CONVERT_RELATIVE_PATH);
append(p_target);
append(p_path);
}

void GDScriptByteCodeGenerator::start_block() {
push_stack_identifiers();
}
Expand Down
1 change: 1 addition & 0 deletions modules/gdscript/gdscript_byte_codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
virtual void write_newline(int p_line) override;
virtual void write_return(const Address &p_return_value) override;
virtual void write_assert(const Address &p_test, const Address &p_message) override;
virtual void write_convert_relative_path(const Address &p_target, const Address &p_path) override;

virtual ~GDScriptByteCodeGenerator();
};
Expand Down
1 change: 1 addition & 0 deletions modules/gdscript/gdscript_codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class GDScriptCodeGenerator {
virtual void write_newline(int p_line) = 0;
virtual void write_return(const Address &p_return_value) = 0;
virtual void write_assert(const Address &p_test, const Address &p_message) = 0;
virtual void write_convert_relative_path(const Address &p_target, const Address &p_path) = 0;

virtual ~GDScriptCodeGenerator() {}
};
Expand Down
29 changes: 29 additions & 0 deletions modules/gdscript/gdscript_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,35 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
gen->write_call_utility(result, call->function_name, arguments);
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptUtilityFunctions::function_exists(call->function_name)) {
// GDScript utility function.
if (call->function_name == "load") {
if (unlikely(call->arguments.is_empty())) {
_set_error("Parser bug: Failed to get load() argument.", call);
r_error = ERR_COMPILATION_FAILED;
return GDScriptCodeGenerator::Address();
}

const GDScriptParser::ExpressionNode *path_expr = call->arguments[0];

if (path_expr->is_constant) {
String path = path_expr->reduced_value;
if (path.is_relative_path()) {
path = main_script->get_path().get_base_dir().path_join(path);
GDScriptCodeGenerator::Address converted_path = codegen.add_constant(path);
if (arguments[0].mode == GDScriptCodeGenerator::Address::TEMPORARY) {
gen->pop_temporary();
}
arguments.write[0] = converted_path;
}
} else {
// `arguments.size() == call->arguments.size()`.
GDScriptCodeGenerator::Address converted_path = codegen.add_temporary(arguments[0].type);
codegen.generator->write_convert_relative_path(converted_path, arguments[0]);
if (arguments[0].mode == GDScriptCodeGenerator::Address::TEMPORARY) {
gen->pop_temporary();
}
arguments.write[0] = converted_path;
}
}
gen->write_call_gdscript_utility(result, call->function_name, arguments);
} else {
// Regular function.
Expand Down
8 changes: 8 additions & 0 deletions modules/gdscript/gdscript_disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
DISASSEMBLE_TYPE_ADJUST(PACKED_VECTOR3_ARRAY);
DISASSEMBLE_TYPE_ADJUST(PACKED_COLOR_ARRAY);

case OPCODE_CONVERT_RELATIVE_PATH: {
text += "convert_relative_path ";
text += DADDR(1);
text += " = ";
text += DADDR(2);

incr += 3;
} break;
case OPCODE_ASSERT: {
text += "assert (";
text += DADDR(1);
Expand Down
3 changes: 2 additions & 1 deletion modules/gdscript/gdscript_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,11 @@ class GDScriptFunction {
OPCODE_TYPE_ADJUST_PACKED_VECTOR2_ARRAY,
OPCODE_TYPE_ADJUST_PACKED_VECTOR3_ARRAY,
OPCODE_TYPE_ADJUST_PACKED_COLOR_ARRAY,
OPCODE_CONVERT_RELATIVE_PATH,
OPCODE_ASSERT,
OPCODE_BREAKPOINT,
OPCODE_LINE,
OPCODE_END
OPCODE_END,
};

enum Address {
Expand Down
18 changes: 18 additions & 0 deletions modules/gdscript/gdscript_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ void (*type_init_function_table[])(Variant *) = {
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR2_ARRAY, \
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR3_ARRAY, \
&&OPCODE_TYPE_ADJUST_PACKED_COLOR_ARRAY, \
&&OPCODE_CONVERT_RELATIVE_PATH, \
&&OPCODE_ASSERT, \
&&OPCODE_BREAKPOINT, \
&&OPCODE_LINE, \
Expand Down Expand Up @@ -3417,6 +3418,23 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_TYPE_ADJUST(PACKED_VECTOR3_ARRAY, PackedVector3Array);
OPCODE_TYPE_ADJUST(PACKED_COLOR_ARRAY, PackedColorArray);

OPCODE(OPCODE_CONVERT_RELATIVE_PATH) {
CHECK_SPACE(3);

GET_VARIANT_PTR(target, 0);
GET_VARIANT_PTR(path_ptr, 1);

String path = *path_ptr;
if (path.is_relative_path()) {
path = _script->get_path().get_base_dir().path_join(path);
}

*target = path;

ip += 3;
}
DISPATCH_OPCODE;

OPCODE(OPCODE_ASSERT) {
CHECK_SPACE(3);

Expand Down
Loading