Skip to content

Commit 56016ee

Browse files
committed
Fix reference object constructor
1 parent 254fe19 commit 56016ee

File tree

5 files changed

+92
-4
lines changed

5 files changed

+92
-4
lines changed

ecmascript_instance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class ECMAScriptInstance : public ScriptInstance {
2222
virtual bool get(const StringName &p_name, Variant &r_ret) const override;
2323
virtual void get_property_list(List<PropertyInfo> *p_properties) const override;
2424
virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const override;
25+
virtual bool property_can_revert(const StringName &p_name) const override { return false; };
26+
virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const override { return false; };
2527

2628
virtual void get_method_list(List<MethodInfo> *p_list) const override;
2729
virtual bool has_method(const StringName &p_method) const override;

ecmascript_language.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ ECMAScriptLanguage::~ECMAScriptLanguage() {
4848
void ECMAScriptLanguage::init() {
4949
ERR_FAIL_NULL(main_binder);
5050
main_binder->initialize();
51-
execute_file("bin/test.js");
51+
execute_file("modules/ECMAScript/tests/UnitTest.js");
5252
}
5353

5454
void ECMAScriptLanguage::finish() {

ecmascript_language.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class ECMAScriptLanguage : public ScriptLanguage {
3434
}
3535

3636
_FORCE_INLINE_ virtual String get_name() const override { return "JavaScript"; }
37-
const GDNativeInstanceBindingCallbacks *getInstanceBindingCallbacks() const { return &instance_binding_callbacks; }
37+
const GDNativeInstanceBindingCallbacks *get_instance_binding_callbacks() const { return &instance_binding_callbacks; }
3838
#ifdef TOOLS_ENABLED
3939
_FORCE_INLINE_ HashSet<Ref<ECMAScript> > &get_scripts() { return scripts; }
4040
#endif

quickjs/quickjs_binder.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct GodotMethodArguments {
5050
_FORCE_INLINE_ static ECMAScriptGCHandler *BINDING_DATA_FROM_GD(Object *p_object) {
5151
ERR_FAIL_COND_V(p_object == NULL, NULL);
5252
ECMAScriptLanguage *lang = ECMAScriptLanguage::get_singleton();
53-
ECMAScriptGCHandler *bind = (ECMAScriptGCHandler *)(p_object)->get_instance_binding(lang, lang->getInstanceBindingCallbacks());
53+
ECMAScriptGCHandler *bind = (ECMAScriptGCHandler *)(p_object)->get_instance_binding(lang, lang->get_instance_binding_callbacks());
5454
return bind;
5555
}
5656

@@ -1587,6 +1587,7 @@ Error QuickJSBinder::bind_gc_object(JSContext *ctx, ECMAScriptGCHandler *data, O
15871587
if (p_object->is_ref_counted()) {
15881588
RefCounted *ref = Object::cast_to<RefCounted>(p_object);
15891589
data->flags |= ECMAScriptGCHandler::FLAG_REFERENCE;
1590+
#if 0
15901591
union {
15911592
Ref<RefCounted> *ref;
15921593
struct {
@@ -1596,6 +1597,9 @@ Error QuickJSBinder::bind_gc_object(JSContext *ctx, ECMAScriptGCHandler *data, O
15961597
u.ref = memnew(Ref<RefCounted>);
15971598
u.r->ref = ref;
15981599
data->godot_reference = u.ref;
1600+
#else
1601+
data->godot_reference = memnew(Ref<RefCounted>(ref));
1602+
#endif
15991603
}
16001604
JS_SetOpaque(obj, data);
16011605
#ifdef DUMP_LEAKS
@@ -1633,7 +1637,10 @@ JSValue QuickJSBinder::object_constructor(JSContext *ctx, JSValueConst new_targe
16331637
js_obj = new_target;
16341638
} else {
16351639
Object *gd_obj = cls.gdclass->creation_func();
1636-
bind = BINDING_DATA_FROM_GD(ctx, gd_obj);
1640+
ECMAScriptLanguage *lang = ECMAScriptLanguage::get_singleton();
1641+
bind = new_gc_handler(ctx);
1642+
bind_gc_object(ctx, bind, gd_obj);
1643+
gd_obj->set_instance_binding(lang, bind, lang->get_instance_binding_callbacks());
16371644
js_obj = JS_MKPTR(JS_TAG_OBJECT, bind->ecma_object);
16381645

16391646
if (JS_IsFunction(ctx, new_target)) {

tests/UnitTest.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// @ts-nocheck
2+
const TEST_ENTRIES = new Map();
3+
4+
5+
test('godot', typeof godot === 'object', 'core');
6+
test('new Object', () => {
7+
let obj = new godot.Object();
8+
let ok = obj && obj instanceof godot.Object;
9+
obj.free();
10+
return ok;
11+
}, 'core');
12+
13+
test('new Resource', () => {
14+
let obj = new godot.Resource();
15+
let ok = obj && obj.get_class() === 'Resource';
16+
return ok;
17+
}, 'core');
18+
19+
20+
// --------------------------- Unit Test Implementation ------------------------
21+
function test(description, blcok, group = 'default') {
22+
const entries = TEST_ENTRIES.get(group) || [];
23+
entries.push({ description, blcok });
24+
TEST_ENTRIES.set(group, entries);
25+
}
26+
function runEntry(entry) {
27+
return new Promise((resolve, reject) => {
28+
switch (typeof (entry.blcok)) {
29+
case 'boolean':
30+
return resolve(entry.blcok);
31+
case 'function': {
32+
try {
33+
resolve(entry.blcok());
34+
} catch (error) {
35+
console.error(error);
36+
resolve(false);
37+
}
38+
}
39+
break;
40+
case 'object':
41+
if (entry.blcok instanceof Promise) {
42+
entry.blcok.then(() => {
43+
resolve(true);
44+
}).catch(err => {
45+
resolve(false);
46+
});
47+
}
48+
break;
49+
default:
50+
return resolve(false);
51+
}
52+
});
53+
}
54+
async function run() {
55+
let count = 0;
56+
let passed = 0;
57+
for (const [group, entries] of TEST_ENTRIES) {
58+
console.log(`Start test ${group}`);
59+
count += entries.length;
60+
let groupCount = 0;
61+
for (let i = 0; i < entries.length; i++) {
62+
const entry = entries[i];
63+
const ret = await runEntry(entry);
64+
if (ret) {
65+
passed++;
66+
groupCount++;
67+
console.log(`\t[${i + 1}/${entries.length}][ √ ] ${entry.description}`);
68+
}
69+
else {
70+
console.error(`\t[${i + 1}/${entries.length}][ X ] ${entry.description}`);
71+
}
72+
}
73+
const logFunc2 = groupCount == entries.length ? console.log : console.warn;
74+
logFunc2(`\tTest ${group} finished: ${groupCount}/${entries.length} passed`);
75+
}
76+
const logFunc = passed == count ? console.log : console.warn;
77+
logFunc(`Test complete: ${passed}/${count} passed`);
78+
}
79+
const _ = run(); // QuickJS BUG ? 返回的是一个 Promise 对象,不赋给临时变量,会导致 Promise 对象无法被 GC

0 commit comments

Comments
 (0)