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

Use generator trampolines during instantiation #32611

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 236 additions & 48 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,26 @@ namespace ts {
};
}

export function* mapByIterator<T, U, TOut, TIn>(iter: IterableIterator<T>, mapFn: (x: T, idx: number) => Generator<TOut, U, TIn>): Generator<TOut, U[] | undefined, TIn> {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export function* mapByIterator<T, U, TOut, TIn>(iter: IterableIterator<T>, mapFn: (x: T, idx: number) => Generator<TOut, U, TIn>): Generator<TOut, U[] | undefined, TIn> {
export function* mapIterator<T, U, TOut, TIn>(iter: IterableIterator<T>, mapFn: (x: T, idx: number) => Generator<TOut, U, TIn>): Generator<TOut, U[] | undefined, TIn> {

Copy link
Member Author

Choose a reason for hiding this comment

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

    export function mapIterator<T, U>(iter: Iterator<T>, mapFn: (x: T) => U): Iterator<U> {
        return {
            next() {
                const iterRes = iter.next();
                return iterRes.done ? iterRes as { done: true, value: never } : { value: mapFn(iterRes.value), done: false };
            }
        };
    }

already exists, except that applies a mapping function to an iterator, rather than applying a mapping generator to an iterator~

let i = 0;
let result: U[] | undefined;
for (const e of iter) {
(result || (result = [])).push(yield* mapFn(e, i));
i++;
}
return result;
}


export function collectGeneratorReturn<TYield, TStep, TReturn>(gen: Generator<TYield, TReturn, TStep>, feedforward: (yielded: TYield) => TStep): TReturn {
let result;
for (result = gen.next(); !result.done;) {
result = gen.next(feedforward(result.value as TYield));
}
return (result as IteratorReturnResult<TReturn>).value;
}


// Maps from T to T and avoids allocation if all elements map to themselves
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[];
export function sameMap<T>(array: ReadonlyArray<T>, f: (x: T, i: number) => T): ReadonlyArray<T>;
Expand Down
1 change: 1 addition & 0 deletions src/tsconfig-base.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

"alwaysStrict": true,
"preserveConstEnums": true,
"downlevelIteration": true,
Copy link
Member Author

@weswigham weswigham Jul 29, 2019

Choose a reason for hiding this comment

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

#32221 tracks what we'd need to do to target native generators (mostly fixing TDZ bugs to do with real runtime const/let), which is pretty appealing at this point, since all versions of node we support use them, and they consume roughly 1/3rd of the memory of the downlevel form.

Copy link
Member

@rbuckton rbuckton Jul 30, 2019

Choose a reason for hiding this comment

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

"downlevelIteration" will seriously degrade the performance of all of our for..of statements in the compiler. Using native generators would also be a problem for VSCode/Monaco as they still have web hosting scenarios they need to support where native generators are not available.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh yeah, I know - that's why I did testing with native generators (and other es6 features). Native generators are fine for most people, though, and we can always just ship a secondary bundle with downleveled generators for older webhosts.

"newLine": "lf",

"types": []
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading