Skip to content

Fix InvalidCastException when a property getter is a bound function#2301

Merged
lahma merged 2 commits into
mainfrom
copilot/fix-invalidcastexception-getter
Mar 1, 2026
Merged

Fix InvalidCastException when a property getter is a bound function#2301
lahma merged 2 commits into
mainfrom
copilot/fix-invalidcastexception-getter

Conversation

Copilot AI commented Mar 1, 2026

Copy link
Copy Markdown
Contributor

ObjectInstance.UnwrapFromGetter and PrivateGet both cast the getter directly to Function.Function, but BindFunction extends ObjectInstance directly (not Function) and only implements ICallable. This causes an InvalidCastException when accessing a property whose getter was created via .bind().

const holder = { x: 42, getter() { return this.x; } };
const target = {};
Object.defineProperty(target, "prop", { get: holder.getter.bind(holder) });
target.prop; // throws InvalidCastException before fix, returns 42 after

Changes

  • ObjectInstance.UnwrapFromGetter: Replace direct (Function.Function) cast with ICallable. Route the call through engine.Call(callable, thisObject, Arguments.Empty, null) (engine accessed via (ObjectInstance)getter) — this handles all callable types (BindFunction, JsProxy, etc.) while preserving call-stack management required by the debugger.
  • ObjectInstance.PrivateGet: Same fix; uses the already-available _engine instance field.
  • FunctionTests: Add regression test BoundFunctionCanBeUsedAsPropertyGetter.
Original prompt

This section details on the original issue you should resolve

<issue_title>Object getter can throw InvalidCastException for BindFunction</issue_title>
<issue_description>When an object property is defined as a getter, which in turn is a bound function, accessing the property results in InvalidCastException in ObjectInstance.UnwrapFromGetter, because getter variable is Jint.Native.Function.BindFunction instead of Jint.Native.Function.Function.

Explicit test for BindFunction is not ideal and perhaps ICallable should be used, but I'm not sure how to properly pass it to Engine.

Test code to reproduce the behavior:

Console.WriteLine(new Engine().Evaluate("""
	const holder = {
		x: 42,
		getter() { return this.x; }
	};

	const target = {};

	Object.defineProperty(target, "prop", { get: holder.getter.bind(holder) });

	target.prop;
"""));

Before fix: throws InvalidCastException
After fix: prints out 42</issue_description>

<agent_instructions>You must check the original PR fix attempt and the code review notes when deriving a fix. Find spec-compliant and logical solution.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@lahma See discussion and code review at https://github.com//pull/2299

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: lahma <171892+lahma@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix InvalidCastException for BindFunction in object getter Fix InvalidCastException when a property getter is a bound function Mar 1, 2026
Copilot finished work on behalf of lahma March 1, 2026 09:33
@lahma
lahma marked this pull request as ready for review March 1, 2026 10:06
@lahma
lahma merged commit efce8dc into main Mar 1, 2026
4 checks passed
@lahma
lahma deleted the copilot/fix-invalidcastexception-getter branch March 1, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Object getter can throw InvalidCastException for BindFunction

2 participants