-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[WIP] Add promise.any #6301
[WIP] Add promise.any #6301
Conversation
29f2370
to
e87d1ee
Compare
One note to help you - the test failures are because the self-hosted Javascript for JsBuiltins and INTL needs to be regenerated (a side effect of having added the ENTRY for To fix this you'll need to run the script called |
e87d1ee
to
a99e4b0
Compare
@rhuanjl Thanks, I realized that. |
The script should have given you 8 files - it appears you only checked in 4 of them. |
a99e4b0
to
4294792
Compare
6e09f83
to
c6985de
Compare
cbd9bbf
to
044d5fa
Compare
Hi, I think i need some help... I have several questions:
Thanks |
|
@rhuanjl Thank you for your help! |
@Kingwl In addition to what @rhuanjl says, I think it would be better if we could subclass Also, thanks for working on this one! |
@zenparsing Thanks for the response |
The scripts that regen bytecode only work on windows BUT you could fairly easily hack it to work on macOS or Linux for testing BUT not for submitting because you need to submit updated bytecode for x64 and x86 - generating the x86 bytecode requires an x86 build of CC and currently on macOS and Linux you can only do x64 builds. |
It's too hard to (seems) make that work... |
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.
Thank you for what you've done here, this is an amazing effort. I hope you'd like to continue to work on it? I'm sorry for the big delay from October - the future ownership of ChakraCore is transitioning, see #6384 for more details.
I've done an initial review - and left some comments, additionally:
- some tests for AggregateError when used on its own are needed
- I've not been through the time travel debug code yet - we'll also need TTD behaviour tests, though could potentially submit this with TTD as a pending/todo part.
@@ -2139,6 +2139,19 @@ using namespace Js; | |||
return TRUE; | |||
} | |||
|
|||
JavascriptArray* JavascriptOperators::IterableToList(RecyclableObject* items, ScriptContext* scriptContext) { |
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.
As far as I can see this is only used once, could you just do the steps inline without making a new method for it?
return pError; | ||
} | ||
|
||
void __declspec(noreturn) JavascriptAggregateError::ThrowAggregateError(ScriptContext* scriptContext, RecyclableObject* errors, int32 hCode, EXCEPINFO* pei) |
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.
Do we need all these variants for ThrowAggregateError? Where are they used?
@@ -484,6 +582,12 @@ namespace Js | |||
pError->m_errorType = errorType; | |||
} | |||
|
|||
void JavascriptAggregateError::SetErrorsProperties(JavascriptAggregateError* pError, RecyclableObject* errors) |
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.
Could these steps be inlined when used rather than being a new method, considering how short it is?
JavascriptLibrary* library = scriptContext->GetLibrary(); | ||
JavascriptAggregateError* thisError = VarTo<JavascriptAggregateError>(args[0]); | ||
|
||
RecyclableObject* iterator = JavascriptOperators::GetIterator(thisError->GetErrors(), scriptContext); |
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.
Should do a nullptr check on the errors property - and return a 0 length array if errors is nullptr.
Var newTarget = args.GetNewTarget(); | ||
RecyclableObject* errors = args.Info.Count > 1 ? JavascriptOperators::IterableToList(VarTo<RecyclableObject>(args[1]), scriptContext) : library->CreateArray(0); | ||
Var message = args.Info.Count > 2 ? args[2] : library->GetUndefined(); | ||
pError->SetErrors(errors); |
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.
Should make the errors a nullptr if length would be 0 and skip allocating the array - though will need to add a nullptr check when using it (though that should be added for safety anyway).
|
||
AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Promise.any")); | ||
|
||
// 1. Let C be the this value. |
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.
Should either run the Spec comments all the way through or emit them entirely. I favour having them all the way through if you can.
// 3. Let promiseCapability be NewPromiseCapability(C). | ||
JavascriptPromiseCapability* promiseCapability = NewPromiseCapability(constructor, scriptContext); | ||
|
||
RecyclableObject* constructorObject = VarTo<RecyclableObject>(constructor); |
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.
Could use UnsafeVarTo (excludes a type check) as you've implicitly checked that this conversion will work with the IsObject check above - though perhaps move this up to be straight under the if to make that obvious.
} | ||
|
||
void JavascriptPromiseAnyRejectElementFunction::SetAlreadyCalled(const bool is) | ||
{ |
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.
nit: if using a setter for this no need for a parameter as you'll only ever call it to set to true
function FakePromise(fn) { | ||
function resolve() { echo(`Test #${index} - resolve called`); throw new Error('oops'); } | ||
function reject(e) { echo(`Test #${index} - reject called: ${e.message}`) } | ||
fn(resolve, reject); | ||
this.then = function(onResolve, onReject) {}; | ||
} | ||
|
||
FakePromise.resolve = function() {}; | ||
Promise.any.call(FakePromise, []); |
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.
This test case appears to be broken, or at least does not produce the result in the baseline.
Sorry for the delay too. |
Great thanks. Also, FYI, when you need to regenerate the bytecode headers again - I've recently enabled regenerating the bytecode on macOS or linux if you rebase on the latest master you'll find a script that can do this: https://github.com/microsoft/ChakraCore/blob/master/tools/xplatRegenByteCode.py |
@Kingwl are you likely to pick this up again? Would be good to get it finished |
Sorry again. I almost(well, exactly) forgot about this issue. BTW: I have join Microsoft. :XD |
It would be great to get this in if we can, though I note further to the points above:
|
@Kingwl, when you will work on this PR, please update AggregateError to complete implementation of Error cause proposal and resolve a TODO in error_cause.js test (Edit: Note that you must write separate tests for AggregateError because of errors parameter) |
WIP, not finally patch
FIxes #6299