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

Reduce number of addressing modes in GDScript VM #47727

Merged
merged 1 commit into from
Apr 9, 2021
Merged
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
44 changes: 21 additions & 23 deletions modules/gdscript/gdscript_byte_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,7 @@ uint32_t GDScriptByteCodeGenerator::add_local_constant(const StringName &p_name,
}

uint32_t GDScriptByteCodeGenerator::add_or_get_constant(const Variant &p_constant) {
if (constant_map.has(p_constant)) {
return constant_map[p_constant];
}
int index = constant_map.size();
constant_map[p_constant] = index;
return index;
return get_constant_pos(p_constant);
}

uint32_t GDScriptByteCodeGenerator::add_or_get_name(const StringName &p_name) {
Expand Down Expand Up @@ -612,7 +607,8 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr
} break;
case GDScriptDataType::NATIVE: {
int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3);
append(p_target);
append(p_source);
Expand All @@ -621,8 +617,7 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr
case GDScriptDataType::SCRIPT:
case GDScriptDataType::GDSCRIPT: {
Variant script = p_target.type.script_type;
int idx = get_constant_pos(script);
idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);

append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3);
append(p_target);
Expand Down Expand Up @@ -673,6 +668,12 @@ void GDScriptByteCodeGenerator::write_assign_default_parameter(const Address &p_
function->default_arguments.push_back(opcodes.size());
}

void GDScriptByteCodeGenerator::write_store_named_global(const Address &p_dst, const StringName &p_global) {
append(GDScriptFunction::OPCODE_STORE_NAMED_GLOBAL, 1);
append(p_dst);
append(p_global);
}

void GDScriptByteCodeGenerator::write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) {
int index = 0;

Expand All @@ -683,16 +684,14 @@ void GDScriptByteCodeGenerator::write_cast(const Address &p_target, const Addres
} break;
case GDScriptDataType::NATIVE: {
int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_type.native_type];
class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
append(GDScriptFunction::OPCODE_CAST_TO_NATIVE, 3);
index = class_idx;
index = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
} break;
case GDScriptDataType::SCRIPT:
case GDScriptDataType::GDSCRIPT: {
Variant script = p_type.script_type;
int idx = get_constant_pos(script);
idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);

int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
append(GDScriptFunction::OPCODE_CAST_TO_SCRIPT, 3);
index = idx;
} break;
Expand Down Expand Up @@ -903,7 +902,7 @@ void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const S
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
append(GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
append(p_target);
append(p_arguments.size());
append(p_function_name);
Expand All @@ -914,7 +913,7 @@ void GDScriptByteCodeGenerator::write_call_self_async(const Address &p_target, c
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
append(GDScriptFunction::ADDR_SELF);
append(p_target);
append(p_arguments.size());
append(p_function_name);
Expand Down Expand Up @@ -999,7 +998,7 @@ void GDScriptByteCodeGenerator::write_construct_typed_array(const Address &p_tar
if (p_element_type.script_type) {
Variant script_type = Ref<Script>(p_element_type.script_type);
int addr = get_constant_pos(script_type);
addr |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS;
addr |= GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS;
append(addr);
} else {
append(Address()); // null.
Expand Down Expand Up @@ -1296,8 +1295,7 @@ void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) {
const GDScriptDataType &element_type = function->return_type.get_container_element_type();

Variant script = function->return_type.script_type;
int script_idx = get_constant_pos(script);
script_idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
int script_idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);

append(GDScriptFunction::OPCODE_RETURN_TYPED_ARRAY, 2);
append(p_return_value);
Expand Down Expand Up @@ -1326,7 +1324,7 @@ void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) {

Variant script = function->return_type.script_type;
int script_idx = get_constant_pos(script);
script_idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
script_idx |= (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);

append(GDScriptFunction::OPCODE_RETURN_TYPED_ARRAY, 2);
append(p_return_value);
Expand All @@ -1343,14 +1341,14 @@ void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) {
append(GDScriptFunction::OPCODE_RETURN_TYPED_NATIVE, 2);
append(p_return_value);
int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[function->return_type.native_type];
class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
append(class_idx);
} break;
case GDScriptDataType::GDSCRIPT:
case GDScriptDataType::SCRIPT: {
Variant script = function->return_type.script_type;
int script_idx = get_constant_pos(script);
script_idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
int script_idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);

append(GDScriptFunction::OPCODE_RETURN_TYPED_SCRIPT, 2);
append(p_return_value);
Expand Down
22 changes: 8 additions & 14 deletions modules/gdscript/gdscript_byte_codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
List<Map<StringName, int>> block_identifier_stack;
Map<StringName, int> block_identifiers;

int current_stack_size = 0;
int current_stack_size = 3; // First 3 spots are reserved for self, class, and nil.
int current_temporaries = 0;
int current_locals = 0;
int current_line = 0;
int stack_max = 0;
int stack_max = 3;
int instr_args_max = 0;
int ptrcall_max = 0;

Expand Down Expand Up @@ -135,7 +135,7 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
ERR_PRINT("Leaving block with non-zero temporary variables: " + itos(current_temporaries));
}
#endif
current_stack_size = current_locals;
current_stack_size = current_locals + 3; // Keep the 3 reserved slots for self, class, and nil.

if (debug_stack) {
for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) {
Expand Down Expand Up @@ -300,26 +300,19 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
int address_of(const Address &p_address) {
switch (p_address.mode) {
case Address::SELF:
return GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS;
return GDScriptFunction::ADDR_SELF;
case Address::CLASS:
return GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS;
return GDScriptFunction::ADDR_CLASS;
case Address::MEMBER:
return p_address.address | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS);
case Address::CLASS_CONSTANT:
return p_address.address | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS);
case Address::LOCAL_CONSTANT:
case Address::CONSTANT:
return p_address.address | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
return p_address.address | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
case Address::LOCAL_VARIABLE:
case Address::TEMPORARY:
case Address::FUNCTION_PARAMETER:
return p_address.address | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
case Address::GLOBAL:
return p_address.address | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
case Address::NAMED_GLOBAL:
return p_address.address | (GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL << GDScriptFunction::ADDR_BITS);
case Address::NIL:
return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
return GDScriptFunction::ADDR_NIL;
}
return -1; // Unreachable.
}
Expand Down Expand Up @@ -441,6 +434,7 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
virtual void write_assign_true(const Address &p_target) override;
virtual void write_assign_false(const Address &p_target) override;
virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src) override;
virtual void write_store_named_global(const Address &p_dst, const StringName &p_global) override;
virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) override;
virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
Expand Down
5 changes: 1 addition & 4 deletions modules/gdscript/gdscript_codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,9 @@ class GDScriptCodeGenerator {
CLASS,
MEMBER,
CONSTANT,
CLASS_CONSTANT,
LOCAL_CONSTANT,
LOCAL_VARIABLE,
FUNCTION_PARAMETER,
TEMPORARY,
GLOBAL,
NAMED_GLOBAL,
NIL,
};
AddressMode mode = NIL;
Expand Down Expand Up @@ -123,6 +119,7 @@ class GDScriptCodeGenerator {
virtual void write_assign_true(const Address &p_target) = 0;
virtual void write_assign_false(const Address &p_target) = 0;
virtual void write_assign_default_parameter(const Address &dst, const Address &src) = 0;
virtual void write_store_named_global(const Address &p_dst, const StringName &p_global) = 0;
virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) = 0;
virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
Expand Down
9 changes: 6 additions & 3 deletions modules/gdscript/gdscript_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
GDScriptNativeClass *nc = nullptr;
while (scr) {
if (scr->constants.has(identifier)) {
return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here.
return codegen.add_constant(scr->constants[identifier]); // TODO: Get type here.
}
if (scr->native.is_valid()) {
nc = scr->native.ptr();
Expand Down Expand Up @@ -319,7 +319,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code

if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier];
return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::GLOBAL, idx); // TODO: Get type.
Variant global = GDScriptLanguage::get_singleton()->get_global_array()[idx];
return codegen.add_constant(global); // TODO: Get type.
}

// Try global classes.
Expand Down Expand Up @@ -347,7 +348,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code

#ifdef TOOLS_ENABLED
if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::NAMED_GLOBAL, gen->add_or_get_name(identifier)); // TODO: Get type.
GDScriptCodeGenerator::Address global = codegen.add_temporary(); // TODO: Get type.
gen->write_store_named_global(global, identifier);
return global;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion modules/gdscript/gdscript_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class GDScriptCompiler {

GDScriptCodeGenerator::Address add_local_constant(const StringName &p_name, const Variant &p_value) {
uint32_t addr = generator->add_local_constant(p_name, p_value);
locals[p_name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::LOCAL_CONSTANT, addr);
locals[p_name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CONSTANT, addr);
return locals[p_name];
}

Expand Down
42 changes: 19 additions & 23 deletions modules/gdscript/gdscript_disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,35 +69,23 @@ static String _disassemble_address(const GDScript *p_script, const GDScriptFunct
int addr = p_address & GDScriptFunction::ADDR_MASK;

switch (p_address >> GDScriptFunction::ADDR_BITS) {
case GDScriptFunction::ADDR_TYPE_SELF: {
return "self";
} break;
case GDScriptFunction::ADDR_TYPE_CLASS: {
return "class";
} break;
case GDScriptFunction::ADDR_TYPE_MEMBER: {
return "member(" + p_script->debug_get_member_by_index(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT: {
return "class_const(" + p_function.get_global_name(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT: {
case GDScriptFunction::ADDR_TYPE_CONSTANT: {
return "const(" + _get_variant_string(p_function.get_constant(addr)) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_STACK: {
return "stack(" + itos(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_STACK_VARIABLE: {
return "var_stack(" + itos(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_GLOBAL: {
return "global(" + _get_variant_string(GDScriptLanguage::get_singleton()->get_global_array()[addr]) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL: {
return "named_global(" + p_function.get_global_name(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_NIL: {
return "nil";
switch (addr) {
case GDScriptFunction::ADDR_STACK_SELF:
return "self";
case GDScriptFunction::ADDR_STACK_CLASS:
return "class";
case GDScriptFunction::ADDR_STACK_NIL:
return "nil";
default:
return "stack(" + itos(addr) + ")";
}
} break;
}

Expand Down Expand Up @@ -885,6 +873,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
incr += 5;
} break;
DISASSEMBLE_ITERATE_TYPES(DISASSEMBLE_ITERATE);
case OPCODE_STORE_NAMED_GLOBAL: {
text += "store named global ";
text += DADDR(1);
text += " = ";
text += String(_global_names_ptr[_code_ptr[ip + 2]]);

incr += 3;
} break;
case OPCODE_LINE: {
int line = _code_ptr[ip + 1] - 1;
if (line >= 0 && line < p_code_lines.size()) {
Expand Down
24 changes: 13 additions & 11 deletions modules/gdscript/gdscript_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ class GDScriptFunction {
OPCODE_ITERATE_PACKED_VECTOR3_ARRAY,
OPCODE_ITERATE_PACKED_COLOR_ARRAY,
OPCODE_ITERATE_OBJECT,
OPCODE_STORE_NAMED_GLOBAL,
OPCODE_ASSERT,
OPCODE_BREAKPOINT,
OPCODE_LINE,
Expand All @@ -360,16 +361,18 @@ class GDScriptFunction {
ADDR_BITS = 24,
ADDR_MASK = ((1 << ADDR_BITS) - 1),
ADDR_TYPE_MASK = ~ADDR_MASK,
ADDR_TYPE_SELF = 0,
ADDR_TYPE_CLASS = 1,
ADDR_TYPE_STACK = 0,
ADDR_TYPE_CONSTANT = 1,
ADDR_TYPE_MEMBER = 2,
ADDR_TYPE_CLASS_CONSTANT = 3,
ADDR_TYPE_LOCAL_CONSTANT = 4,
ADDR_TYPE_STACK = 5,
ADDR_TYPE_STACK_VARIABLE = 6,
ADDR_TYPE_GLOBAL = 7,
ADDR_TYPE_NAMED_GLOBAL = 8,
ADDR_TYPE_NIL = 9
};

enum FixedAddresses {
ADDR_STACK_SELF = 0,
ADDR_STACK_CLASS = 1,
ADDR_STACK_NIL = 2,
ADDR_SELF = ADDR_STACK_SELF | (ADDR_TYPE_STACK << ADDR_BITS),
ADDR_CLASS = ADDR_STACK_CLASS | (ADDR_TYPE_STACK << ADDR_BITS),
ADDR_NIL = ADDR_STACK_NIL | (ADDR_TYPE_STACK << ADDR_BITS),
};

enum Instruction {
Expand Down Expand Up @@ -462,7 +465,7 @@ class GDScriptFunction {

List<StackDebug> stack_debug;

_FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const;
_FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, Variant *p_stack, String &r_error) const;
_FORCE_INLINE_ String _get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const;

friend class GDScriptLanguage;
Expand Down Expand Up @@ -497,7 +500,6 @@ class GDScriptFunction {
#endif
Vector<uint8_t> stack;
int stack_size = 0;
Variant self;
uint32_t alloca_size = 0;
int ip = 0;
int line = 0;
Expand Down
Loading