Skip to content
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
16 changes: 13 additions & 3 deletions bridge/jsb_environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@

void Environment::init()
{
jsb::DefaultModuleResolver& resolver = this->add_module_resolver<jsb::DefaultModuleResolver>()

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🤖 Android / Android (template_debug, qjs-ng)

unused variable 'resolver'

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🌐 Web / Web (template_debug, qjs-ng, threads=yes, dlink=no)

unused variable 'resolver'

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🌐 Web / Web (template_debug, browser, threads=yes, dlink=no)

unused variable 'resolver'

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🍏 iOS / iOS (template_debug, qjs-ng)

unused variable 'resolver'

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🏁 Windows / Windows (editor, v8)

'resolver': local variable is initialized but not referenced

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🏁 Windows / Windows (editor, qjs-ng)

'resolver': local variable is initialized but not referenced

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🍎 macOS / Mac (editor, qjs-ng)

unused variable 'resolver'

Check warning on line 450 in bridge/jsb_environment.cpp

View workflow job for this annotation

GitHub Actions / ⚙️ Build Godot Version with GodotJS (4.6.1, 4.6, 4.6.1-stable) / 🍎 macOS / Mac (editor, qjs-ng)

unused variable 'resolver'
.add_search_path(jsb::internal::Settings::get_jsb_out_res_path()) // default path of js source (results of compiled ts, at '.godot/GodotJS' by default)
.add_search_path("res://") // use the root directory as custom lib path by default
.add_search_path("res://node_modules") // so far, it's the only supported path for node_modules in GodotJS
Expand Down Expand Up @@ -940,16 +940,26 @@
{
if (object_handle->ref_count_ == 0)
{
// becomes a strong reference
jsb_check(!object_handle->ref_.IsEmpty());
// A first-pass GC callback may already have reset `ref_` while second-pass free
// is still pending. Treat this as a stale/dead binding instead of crashing.
if (jsb_unlikely(object_handle->ref_.IsEmpty()))
{
JSB_LOG(Warning, "UNEXPECTED inc reference on dead value %d", (uintptr_t) p_pointer);
return false;
}
object_handle->ref_.ClearWeak();
}
++object_handle->ref_count_;
return true;
}

// removing references
jsb_checkf(!object_handle->ref_.IsEmpty(), "removing references on dead values");
if (jsb_unlikely(object_handle->ref_.IsEmpty()))
{
JSB_LOG(Warning, "UNEXPECTED dec reference on dead value %d", (uintptr_t) p_pointer);
return false;
}

jsb_check(object_handle->ref_count_ > 0);

--object_handle->ref_count_;
Expand Down
35 changes: 32 additions & 3 deletions bridge/jsb_environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -658,11 +658,40 @@ namespace jsb
*/
void call_script_prelude(ScriptClassID p_script_class_id, NativeObjectID p_object_id);

// callback from v8 gc (not 100% guaranteed called)
// NOTE: First-pass weak callbacks are very restricted in V8. Do not do heavy work there.
jsb_force_inline static void object_gc_callback(const v8::WeakCallbackInfo<void>& info)
{
Environment* env = wrap(info.GetIsolate());
env->add_async_call(AsyncCall::TYPE_GC_FREE, info.GetParameter());
if (Environment* env = wrap(info.GetIsolate()))
{
// V8 requires clearing the weak handle in first-pass callbacks.
if (ObjectHandlePtr object_handle = env->object_db_.try_get_object(info.GetParameter()))
{
object_handle->ref_.Reset();
}

if (!env->is_disposing())
{
#if JSB_WITH_V8
info.SetSecondPassCallback(&object_gc_callback_second_pass);
#else
object_gc_callback_second_pass(info);
#endif
}
}
}

static void object_gc_callback_second_pass(const v8::WeakCallbackInfo<void>& info)
{
if (Environment* env = wrap(info.GetIsolate()))
{
// During shutdown we explicitly drain object_db_ in dispose(); skip GC callback work.
if (env->is_disposing())
{
return;
}

env->add_async_call(AsyncCall::TYPE_GC_FREE, info.GetParameter());
}
}

// a forward method for non-v8 implementations
Expand Down
Loading