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

Feature problem: yieldEach #453

Open
Yi2255 opened this issue Oct 14, 2024 · 4 comments
Open

Feature problem: yieldEach #453

Yi2255 opened this issue Oct 14, 2024 · 4 comments

Comments

@Yi2255
Copy link
Contributor

Yi2255 commented Oct 14, 2024

Problem

By JS definition MDN , what is passed to yieldeach must be an iterable object.

YieldGenerator, GeneratorFunctionGenerator, AsyncGeneratorFunctionGenerator use b.yieldEach(b.randomVariable()),

where randomVariable is likely to be a non-iteratable object such as an integer.

Q:

I believe I might be able to fix this issue by buildIteratorVariable method that can generate some iterable objects. Would it be alright if I submitted a pull request to address this?

@saelo
Copy link
Collaborator

saelo commented Oct 16, 2024

Thanks for filing this, and sure, please send a PR! I think the right approach though would be to try and obtain a random variable of type .iterable. If that doesn't work, we should use a guard to avoid an unhandled exception at runtime (assuming that's possible for yield*)

@Yi2255
Copy link
Contributor Author

Yi2255 commented Oct 17, 2024

Thanks for your feedback!

I agree with getting a random variable of type .iterable, as this would help ensure the correctness of yield*. But I still have two questions:

  1. Is it possible to do this: instead of using a guard, replace the input with a random variable of type .iterable, and it will look for an iterable from the context, and if there is none, call our own method to generate .iterable objects .
  2. I understand the idea of using a guard at runtime to handle runtime errors. However, I would like to know why you prefer to use a guard to ensure runtime correctness rather than ensuring correctness during the generation phase, for example, by avoiding the generation of invalid constructs (such as infinite recursion or cyclic assignments).

Thnaks again!

@saelo
Copy link
Collaborator

saelo commented Oct 17, 2024

The HowFuzzilliWorks Doc touches on that a bit (but it should be more detailed...).

One reason is that our type analysis is very basic, so for a lot of the variables we don't know their type. If we were very conservative with our code generation (e.g. what you describe, use only input variables of known-correct types and otherwise generate new code), then there would be many variables in the program that we would never use in certain ways (because we don't know their types). On the other hand, we'd generate a lot of code like yield* [1,2,3] (where we generated a .iterable), but that's also not particularly interesting, probably. So instead the idea is that we'd just try random variables and use a try-catch, and if we're lucky, our minimizer will just remove the try-catch again.

The other thing is that value generation is very biased in the sense that if you do value generation for a .iterable, you will probably always emit an ArrayLiteral. However, there are many other ways of generating a .iterable. Our CodeGenerators take care of emitting such code, but then we still need to use those variables later on, and so we should prefer to use existing variables rather than generating new ones.

Does that make sense and answer your question?

@Yi2255
Copy link
Contributor Author

Yi2255 commented Oct 18, 2024

Thank you for your detailed explanation! Your insights on type analysis and code generation are very helpful!

I will further improve the code based on the direction you mentioned and submit a PR about the issue.

Thank you again for your help!

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

No branches or pull requests

2 participants