-
-
Notifications
You must be signed in to change notification settings - Fork 414
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
Fix Fetch and OpDeref #467
Conversation
Loop over `Ptr` and `Interface` kind and get `Elem`. Also return directly the `nil` otherwise we might are returning the pointer nil value and not the base nil.
We were only de-referencing pointers, but we can have pointer of interface or interface obfuscating pointers... So before trying to fetch anything, just deference fully the variable.
I will have a look tomorrow to see if I can understand where I would need to modify the code to add the |
Results looks promising. |
@@ -28,10 +36,8 @@ func Fetch(from, i any) any { | |||
// Structs, maps, and slices can be access through a pointer or through | |||
// a value, when they are accessed through a pointer we don't want to | |||
// copy them to a value. | |||
if kind == reflect.Ptr { | |||
v = reflect.Indirect(v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we going to loose reflect.Indirect
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is ooriginal change: 6f0c855
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are still doing the "indirect" in the deref
function as we are calling Elem()
of the value is a pointer.
Which should be doing the same as the Indirect
function, which is also doing Elem()
behind the scene:
func Indirect(v Value) Value {
if v.Kind() != Pointer {
return v
}
return v.Elem()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just ran the benchrmak, it seems we are in the same order of magnitude:
before:
Benchmark_largeStructAccess-12 1000000 134.4 ns/op
after:
Benchmark_largeStructAccess-12 1000000 132.2 ns/op
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! let me check it a bit more as runtime changes should be done very carefully.
I was trying to figure out where we would need to add an if op == OpFetch {
c.derefInNeeded(base)
c.compile(node.Property)
c.emit(OpFetch)
} This is fixing the problem when we try to access a field, but introducing a bug when fetch is used to get a method. This test for example is failing: Any idea where I should add a The other solution would be to not add any |
Let's use this for now. |
Lets use this for now. |
First commit is fixing some issue with
runtime.Deref
which is called byOpDeref
, pointer of interface were not de-referenced.Second commit is creating a fix for #466. This is de-referencing everything in
Fetch
before fetching the attribute.As discussed in the issue, one other approach could be to ensure we have a
OpDeref
operation added during the compilation phase.