summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/gdscript/gdscript_byte_codegen.cpp44
-rw-r--r--modules/gdscript/gdscript_byte_codegen.h22
-rw-r--r--modules/gdscript/gdscript_codegen.h5
-rw-r--r--modules/gdscript/gdscript_compiler.cpp9
-rw-r--r--modules/gdscript/gdscript_compiler.h2
-rw-r--r--modules/gdscript/gdscript_disassembler.cpp42
-rw-r--r--modules/gdscript/gdscript_function.h24
-rw-r--r--modules/gdscript/gdscript_vm.cpp173
8 files changed, 128 insertions, 193 deletions
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp
index ec1116197e..b553dcede3 100644
--- a/modules/gdscript/gdscript_byte_codegen.cpp
+++ b/modules/gdscript/gdscript_byte_codegen.cpp
@@ -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) {
@@ -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);
@@ -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);
@@ -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;
@@ -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;
@@ -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);
@@ -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);
@@ -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.
@@ -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);
@@ -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);
@@ -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);
diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h
index 6eaec91504..4b196ed420 100644
--- a/modules/gdscript/gdscript_byte_codegen.h
+++ b/modules/gdscript/gdscript_byte_codegen.h
@@ -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;
@@ -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()) {
@@ -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.
}
@@ -441,6 +434,7 @@ public:
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;
diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h
index 3c05f14cf7..cce4e856c7 100644
--- a/modules/gdscript/gdscript_codegen.h
+++ b/modules/gdscript/gdscript_codegen.h
@@ -45,13 +45,9 @@ public:
CLASS,
MEMBER,
CONSTANT,
- CLASS_CONSTANT,
- LOCAL_CONSTANT,
LOCAL_VARIABLE,
FUNCTION_PARAMETER,
TEMPORARY,
- GLOBAL,
- NAMED_GLOBAL,
NIL,
};
AddressMode mode = NIL;
@@ -123,6 +119,7 @@ public:
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;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 6a91148575..abbca899bd 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -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();
@@ -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.
@@ -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
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 651391f972..1b0beec0d4 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -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];
}
diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp
index 33acbb2a35..74da0ee232 100644
--- a/modules/gdscript/gdscript_disassembler.cpp
+++ b/modules/gdscript/gdscript_disassembler.cpp
@@ -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;
}
@@ -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()) {
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 9fc75b66ce..414dfab2e7 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -350,6 +350,7 @@ public:
OPCODE_ITERATE_PACKED_VECTOR3_ARRAY,
OPCODE_ITERATE_PACKED_COLOR_ARRAY,
OPCODE_ITERATE_OBJECT,
+ OPCODE_STORE_NAMED_GLOBAL,
OPCODE_ASSERT,
OPCODE_BREAKPOINT,
OPCODE_LINE,
@@ -360,16 +361,18 @@ public:
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 {
@@ -462,7 +465,7 @@ private:
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;
@@ -497,7 +500,6 @@ public:
#endif
Vector<uint8_t> stack;
int stack_size = 0;
- Variant self;
uint32_t alloca_size = 0;
int ip = 0;
int line = 0;
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 6b7da4a467..8bf6a8b08b 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -34,22 +34,22 @@
#include "core/os/os.h"
#include "gdscript.h"
-Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const {
+Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, Variant *p_stack, String &r_error) const {
int address = p_address & ADDR_MASK;
//sequential table (jump table generated by compiler)
switch ((p_address & ADDR_TYPE_MASK) >> ADDR_BITS) {
- case ADDR_TYPE_SELF: {
+ case ADDR_TYPE_STACK: {
#ifdef DEBUG_ENABLED
- if (unlikely(!p_instance)) {
- r_error = "Cannot access self without instance.";
- return nullptr;
- }
+ ERR_FAIL_INDEX_V(address, _stack_size, nullptr);
#endif
- return &self;
+ return &p_stack[address];
} break;
- case ADDR_TYPE_CLASS: {
- return &static_ref;
+ case ADDR_TYPE_CONSTANT: {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_INDEX_V(address, _constant_count, nullptr);
+#endif
+ return &_constants_ptr[address];
} break;
case ADDR_TYPE_MEMBER: {
#ifdef DEBUG_ENABLED
@@ -61,65 +61,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
//member indexing is O(1)
return &p_instance->members.write[address];
} break;
- case ADDR_TYPE_CLASS_CONSTANT: {
- //todo change to index!
- GDScript *s = p_script;
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _global_names_count, nullptr);
-#endif
- const StringName *sn = &_global_names_ptr[address];
-
- while (s) {
- GDScript *o = s;
- while (o) {
- Map<StringName, Variant>::Element *E = o->constants.find(*sn);
- if (E) {
- return &E->get();
- }
- o = o->_owner;
- }
- s = s->_base;
- }
-
- ERR_FAIL_V_MSG(nullptr, "GDScriptCompiler bug.");
- } break;
- case ADDR_TYPE_LOCAL_CONSTANT: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _constant_count, nullptr);
-#endif
- return &_constants_ptr[address];
- } break;
- case ADDR_TYPE_STACK:
- case ADDR_TYPE_STACK_VARIABLE: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _stack_size, nullptr);
-#endif
- return &p_stack[address];
- } break;
- case ADDR_TYPE_GLOBAL: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, GDScriptLanguage::get_singleton()->get_global_array_size(), nullptr);
-#endif
- return &GDScriptLanguage::get_singleton()->get_global_array()[address];
- } break;
-#ifdef TOOLS_ENABLED
- case ADDR_TYPE_NAMED_GLOBAL: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _global_names_count, nullptr);
-#endif
- StringName id = _global_names_ptr[address];
-
- if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(id)) {
- return (Variant *)&GDScriptLanguage::get_singleton()->get_named_globals_map()[id];
- } else {
- r_error = "Autoload singleton '" + String(id) + "' has been removed.";
- return nullptr;
- }
- } break;
-#endif
- case ADDR_TYPE_NIL: {
- return &nil;
- } break;
}
ERR_FAIL_V_MSG(nullptr, "Bad code! (unknown addressing mode).");
@@ -340,6 +281,7 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
&&OPCODE_ITERATE_PACKED_VECTOR3_ARRAY, \
&&OPCODE_ITERATE_PACKED_COLOR_ARRAY, \
&&OPCODE_ITERATE_OBJECT, \
+ &&OPCODE_STORE_NAMED_GLOBAL, \
&&OPCODE_ASSERT, \
&&OPCODE_BREAKPOINT, \
&&OPCODE_LINE, \
@@ -415,11 +357,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
r_err.error = Callable::CallError::CALL_OK;
- Variant self;
- Variant static_ref;
Variant retvalue;
Variant *stack = nullptr;
- Variant **instruction_args;
+ Variant **instruction_args = nullptr;
const void **call_args_ptr = nullptr;
int defarg = 0;
@@ -444,7 +384,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
script = p_state->script;
p_instance = p_state->instance;
defarg = p_state->defarg;
- self = p_state->self;
} else {
if (p_argcount != _argument_count) {
@@ -462,55 +401,49 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
}
- alloca_size = sizeof(Variant *) * _instruction_args_size + sizeof(Variant) * _stack_size;
-
- if (alloca_size) {
- uint8_t *aptr = (uint8_t *)alloca(alloca_size);
+ // Add 3 here for self, class, and nil.
+ alloca_size = sizeof(Variant *) * 3 + sizeof(Variant *) * _instruction_args_size + sizeof(Variant) * _stack_size;
- if (_stack_size) {
- stack = (Variant *)aptr;
- for (int i = 0; i < p_argcount; i++) {
- if (!argument_types[i].has_type) {
- memnew_placement(&stack[i], Variant(*p_args[i]));
- continue;
- }
+ uint8_t *aptr = (uint8_t *)alloca(alloca_size);
+ stack = (Variant *)aptr;
- if (!argument_types[i].is_type(*p_args[i], true)) {
- r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_err.argument = i;
- r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
- return Variant();
- }
- if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
- Variant arg;
- Variant::construct(argument_types[i].builtin_type, arg, &p_args[i], 1, r_err);
- memnew_placement(&stack[i], Variant(arg));
- } else {
- memnew_placement(&stack[i], Variant(*p_args[i]));
- }
- }
- for (int i = p_argcount; i < _stack_size; i++) {
- memnew_placement(&stack[i], Variant);
- }
- } else {
- stack = nullptr;
+ for (int i = 0; i < p_argcount; i++) {
+ if (!argument_types[i].has_type) {
+ memnew_placement(&stack[i + 3], Variant(*p_args[i]));
+ continue;
}
- if (_instruction_args_size) {
- instruction_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
+ if (!argument_types[i].is_type(*p_args[i], true)) {
+ r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_err.argument = i;
+ r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
+ return Variant();
+ }
+ if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
+ Variant arg;
+ Variant::construct(argument_types[i].builtin_type, arg, &p_args[i], 1, r_err);
+ memnew_placement(&stack[i + 3], Variant(arg));
} else {
- instruction_args = nullptr;
+ memnew_placement(&stack[i + 3], Variant(*p_args[i]));
}
+ }
+ for (int i = p_argcount + 3; i < _stack_size; i++) {
+ memnew_placement(&stack[i], Variant);
+ }
+ memnew_placement(&stack[ADDR_STACK_NIL], Variant);
+
+ if (_instruction_args_size) {
+ instruction_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
} else {
- stack = nullptr;
instruction_args = nullptr;
}
if (p_instance) {
- self = p_instance->owner;
+ memnew_placement(&stack[ADDR_STACK_SELF], Variant(p_instance->owner));
script = p_instance->script.ptr();
} else {
+ memnew_placement(&stack[ADDR_STACK_SELF], Variant);
script = _script;
}
}
@@ -520,7 +453,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
call_args_ptr = nullptr;
}
- static_ref = script;
+ memnew_placement(&stack[ADDR_STACK_CLASS], Variant(script));
String err_text;
@@ -541,10 +474,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#define CHECK_SPACE(m_space) \
GD_ERR_BREAK((ip + m_space) > _code_size)
-#define GET_VARIANT_PTR(m_v, m_code_ofs) \
- Variant *m_v; \
- m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text); \
- if (unlikely(!m_v)) \
+#define GET_VARIANT_PTR(m_v, m_code_ofs) \
+ Variant *m_v; \
+ m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, stack, err_text); \
+ if (unlikely(!m_v)) \
OPCODE_BREAK;
#else
@@ -552,7 +485,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#define CHECK_SPACE(m_space)
#define GET_VARIANT_PTR(m_v, m_code_ofs) \
Variant *m_v; \
- m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text);
+ m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, stack, err_text);
#endif
@@ -2038,7 +1971,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
memnew_placement(&gdfs->state.stack.write[sizeof(Variant) * i], Variant(stack[i]));
}
gdfs->state.stack_size = _stack_size;
- gdfs->state.self = self;
gdfs->state.alloca_size = alloca_size;
gdfs->state.ip = ip + 2;
gdfs->state.line = line;
@@ -3028,6 +2960,19 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
+ OPCODE(OPCODE_STORE_NAMED_GLOBAL) {
+ CHECK_SPACE(3);
+ int globalname_idx = _code_ptr[ip + 2];
+ GD_ERR_BREAK(globalname_idx < 0 || globalname_idx >= _global_names_count);
+ const StringName *globalname = &_global_names_ptr[globalname_idx];
+
+ GET_INSTRUCTION_ARG(dst, 0);
+ *dst = GDScriptLanguage::get_singleton()->get_named_globals_map()[*globalname];
+
+ ip += 3;
+ }
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSERT) {
CHECK_SPACE(3);