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

implementation of Reflect & Proxy support #1431

Draft
wants to merge 31 commits into
base: master
Choose a base branch
from
Draft

Conversation

rbri
Copy link
Collaborator

@rbri rbri commented Dec 27, 2023

sorry made a mistake during the update/rebase of #1332

This is the current version

@rbri
Copy link
Collaborator Author

rbri commented Dec 27, 2023

current status of the impl

built-ins/Array 188/2670 (7.04%)              built-ins/Array 174/2670 (6.52%)
built-ins/Function 186/505 (36.83%)           built-ins/Function 185/505 (36.63%)
built-ins/JSON 36/140 (25.71%)                built-ins/JSON 28/140 (20.0%)
built-ins/Object 122/3150 (3.87%)             built-ins/Object 102/3150 (3.24%)
built-ins/Promise 404/599 (67.45%)            built-ins/Promise 403/599 (67.28%)
                                              built-ins/Proxy 74/306 (24.18%)
                                              built-ins/Reflect 13/139 (9.35%)
language/expressions/typeof 1/16 (6.25%)      language/expressions/typeof 0/16 (0.0%)
language/statements/for-of 471/725 (64.97%)   language/statements/for-of 470/725 (64.83%)

@rbri
Copy link
Collaborator Author

rbri commented Aug 8, 2024

As mentioned already somewhere, this code is in production in the HtmlUnit project (core-js) for a long time now.

I like to update the stats for the current status of the test suite

built-ins/Proxy 80/311 (25.72%)         was built-ins/Proxy 74/306 (24.18%) before
built-ins/Reflect 26/153 (16.99%)       was built-ins/Reflect 13/139 (9.35%) before

and of course many other minor improvements. You can see the whole diff here HtmlUnit@c926d0f

I think the number are still quite good and it's really frustrating to see this has to chance to get merged....

Or the other way around - @gbrail @p-bakker if you agree to merge this Reflect/Proxy impl, I will take the time and build a new pr that is mergable from this impl.

@rbri
Copy link
Collaborator Author

rbri commented Aug 18, 2024

Another week week passed by without any response from @gbrail or @p-bakker. So i guess there is no interest in this. I'm not really able to understand why but i'm able to accept this.

@rbri rbri closed this Aug 18, 2024
@p-bakker
Copy link
Collaborator

p-bakker commented Aug 18, 2024

I haven't been able to look into this, so dunno whether I agree this is mergeable at this moment

I think the previous comments (see €1332) about the behaviour of Proxy/Reflect in this PR not being 100% standard compliant (due to issues/limitations elsewhere in Rhino) still stands, but maybe if I get a chance to look into the details I agree those issues shouldn't block merging inow

However, even if the conclusion would be that we shouldn't merge this now, I'd like to keep this PR open and work towards being able to merge it in a hopefully not too distant future.

So I hope you don't mind, but I'll reopen it

@p-bakker p-bakker reopened this Aug 18, 2024
@p-bakker
Copy link
Collaborator

By no means a thorough review, but:

  • it seems Reflect is much closer to being spec-compliant. Maybe an idea to merge that independent of Proxy?
  • for Proxy it seems a fair chunk of tests related to invariant checks seem to be failing. Those are the types of EcmaScript incompatibilities I think we don't want to merge, as fixing them later could break code that would've started uses the non-EcmaScript-compatible version

Again: the above 2 comments are by no means a thorough review, but based on a quick glance at the updated test262.properties file

@gbrail
Copy link
Collaborator

gbrail commented Aug 18, 2024

Yeah, sorry, I sometimes lose track of how far along people collectively think that various PRs are, and like email, once they fall to the bottom of the list I sometimes lose track and I need a reminder. (There are tools that help send reminders and add more workflow to PRs -- perhaps we should adopt one!)

Do you think that there are enough tests correctly passing in this PR to warrant merging it? It seemed like we were in an incomplete state from the comments. I'll look at the code and see what I think.

@rbri
Copy link
Collaborator Author

rbri commented Aug 19, 2024

It seemed like we were in an incomplete state from the comments.

As is mention several times (here and at other places) i gave up waiting for get this merged an i use this in HtmlUnit/core-js since December 2023. Not sure why you think this is incomplete.

And i made all the statistics to show that this brings (from my point of view) the implementation of the two features in a similar state that we have for all the others (more than ~80% of the tests are passing).

And there are some problems i can't solve because we have to be backward compatible - also discussed several times that i'm in favor of making a hard cut and break some backward compatible to be able to get closer to the current spec. But without that i see no chance to fix more tests. Good ideas are welcome

@p-bakker
Copy link
Collaborator

p-bakker commented Aug 19, 2024

Just a random test that fails and stands out to me is for example https://github.com/tc39/test262/blob/main/test/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target.js

Just judging the testcode, I don't think it failing has to do with limitations elsewhere in the Rhino codebase, or am I wrong?

I understand the frustration of it not getting merged, but I think we should aim to get each new feature as close as we can possibly get it to the spec, because the reality is that we otherwise never get to finishing up the details

Quite likely your MR as it currently stand already correctly handles the majority of usecases correctly, but unfortunately, when it comes to specs, the devil is in the details....

Besides fixing more of the invariant checks like the one below, I could even see this only getting merged in a v2 (or otherwise behind a flag) if the delete trap cannot currently be implemented in a spec compliant way I'm afraid.

Personally I hope to get a few things resolved in a 1.7.16 release, before we can start to focus on a v2.x.x release, particularly proper block-scoping and hopefully some strict-mode improvements

@gbrail
Copy link
Collaborator

gbrail commented Aug 22, 2024

Sadly I had trouble digesting this but it's very important work and I want to get it in to rhino. Unfortunately it will be a big job to resolve all the conflicts. Would you be willing if I am more diligent about merging it when it's mergeable? Otherwise I can spend time on it but it will take a bit.

@rbri
Copy link
Collaborator Author

rbri commented Aug 22, 2024

I can do that but not during the next weeks. Have some workshops and a bit of vacation...

@@ -1581,7 +1581,7 @@ public void defineOwnProperty(Context cx, Object id, ScriptableObject desc) {
* @param desc the new property descriptor, as described in 8.6.1
* @param checkValid whether to perform validity checks
*/
protected void defineOwnProperty(
protected boolean defineOwnProperty(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change from void to boolean returnType? AFAICT all implementations/overrides of this method only ever return true

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm, found that the returnType is used in (at least) the reflectImpl.

I wonder if this is the way to go about it: the spec says defineProperty doesn't return a value, it just throws if there's an issue with defining the property

So I wonder if instead of changing the returnType of the method and always returning true, it would not be better to leave the existing impl. as is and in the Reflect.defineProperty just add a return true after the call to defineProperty, as you already catch the exception and do a return false there

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@p-bakker
Copy link
Collaborator

Not all new methods in the AbstractEcmaObjectOperations class have the additional Context argument that they are said to have

@@ -3679,6 +3682,10 @@ public static boolean shallowEq(Object x, Object y) {
if (y instanceof Boolean) {
return x.equals(y);
}
} else if (x instanceof SymbolKey) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't x.equals(y) and y.equals(x) yield the same result, so you can so if (x instanceof symbolKey || y instanceof symbolKey) ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that is possible but then the code relies on the assumption that x == null. This is correct here but the null check is so many lines above that it might be overlooked some day.
For me this is the more robust and more readable (because it starts no questions in my mind when reading) version.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k

}
}

// hack to set the right prototype before calling the ctor
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe elaborate a bit on why this is considered a hack/why this hack is needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return newScriptable;
}

private static Object defineProperty(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to return Object? It always returns a boolean, no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is used by a LambdaFunction that expects an impl of Callable here - so i used the signature from Callable

Object prop = ScriptableObject.getProperty(target, (Symbol) args[1]);
return prop == Scriptable.NOT_FOUND ? Undefined.SCRIPTABLE_UNDEFINED : prop;
}
if (args[1] instanceof Double) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think you already mentioned this elsewhere, but likely should check for Number, not Double

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the new pr

@p-bakker p-bakker marked this pull request as draft September 8, 2024 07:15
@p-bakker
Copy link
Collaborator

p-bakker commented Sep 8, 2024

Converted to draft, to indicate that this PR needs some work before it can be considered for merge, just to help the committers to be able to focus on what is really ready to merge

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.

Support ES2015 Proxies & Reflect API
3 participants