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

JIT/VM calls incorrect method #685

Closed
m0rkeulv opened this issue May 19, 2024 · 3 comments · Fixed by HaxeFoundation/haxe#11723
Closed

JIT/VM calls incorrect method #685

m0rkeulv opened this issue May 19, 2024 · 3 comments · Fixed by HaxeFoundation/haxe#11723

Comments

@m0rkeulv
Copy link
Member

m0rkeulv commented May 19, 2024

When testing one of my projects with HL i got this unexpected behavior where the VM seems to call the wrong function, it only happens when the object is retrieved from “container” object. I have created a small project that hopefully should be able to reproduce this problem.

it was compiled on Windows 10 using haxe 4.3.4 and running on Hashlink 1.14.0 (downloaded form the release page here on Git)

Code to reproduce the problem: HL_JIT_Bug.zip

image
image

Replacing the interface used with a typedef pointing to the base class changes the behavior.
It looks like the correct method is called, but it causes an Access Violation,
The debugger also no longer seems to recognize the type showing it as {...}

code to reproduce: HL_JIT_Bug_typedef.zip

image
image

If i change the container to specific type instead of interface (replacing Userwith BasicUser) the code runs fine, so it seems to be related to the interface part.

UPDATE:

After some more experimentation i think i have found the cause of the issue, i think its when one interface inherits/ extends another one and they contain identical member names but returns a type extending the original type. this works on other targets and compiles fine, so i guess this is an issue with the HL VM

//Entity.hx (interface)
 function getVariable(varName:String):Variable
 //  User.hx (interface) (User extends Entity)
 function getVariable(name:String):UserVariable;
@m0rkeulv
Copy link
Member Author

i've been playing around with the code and i got things working, but i am not a hundred percent sure i am not breaking anything. my changes are in safe cast, to me it looks like the issue is that since my other class contains a member that is first in the fields array it breaks and return false without checking if the expected fields are included.

this seems to work fine in what little tesiting i've done

case HVIRTUAL:
		if( to->virt->nfields < t->virt->nfields ) {
			int i, j;
			int matches = 0;
			for(i=0;i<to->virt->nfields;i++) {
				hl_obj_field *f2 = to->virt->fields + i;
				for(j=i; j < t->virt->nfields;j++) {
					hl_obj_field *f1 = t->virt->fields + j;
					if( f1->hashed_name == f2->hashed_name && hl_same_type(f1->t,f2->t) ) {
						matches++;
						break;
					}
				}
			}
			if( matches == to->virt->nfields )
				return true;
		}
		break;
		````

@ncannasse
Copy link
Member

ncannasse commented Jun 18, 2024 via email

@m0rkeulv
Copy link
Member Author

just adding this for some more context, to maybe help find a different root causeof my problem.
if i add this to hl_safe_cast

if (t->kind == HOBJ && to->kind == HVIRTUAL) {
		vdynamic * d =  *(vdynamic**)t->obj->global_value;
		vvirtual* conv = hl_to_virtual(to, d);
		return hl_safe_cast(conv->t, to);
	}

(must of course be before this line to have any effect)

if( t->kind != to->kind )
		return false;

the typedef example also runs just fine, but it feels more like the issue is related to hl_to_virtual and what effect null values for fields ( hl_vfields(v)[i] = NULL; ) has to the later execution.

before i modified the HVIRTUAL case in hl_safe_cast hl_to_virtual would set the field to NULL and this some how made the code try to execute a different method, maybe some kind of index missmatch between the real object type and the interface.

without the code above, the typdef seems to get the same problem, hl_vfields(v)[i] = NULL, and later on it throws an Access Violatio error.

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 a pull request may close this issue.

2 participants