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

CallMethod, CallComputedMethod and Construct now support Spread Elements #238

Merged
merged 5 commits into from
Sep 10, 2021

Conversation

amarekano
Copy link
Contributor

No description provided.

@amarekano amarekano force-pushed the extend-spread-element-support branch 3 times, most recently from d091a59 to 07be3e9 Compare August 2, 2021 13:45
@amarekano amarekano force-pushed the extend-spread-element-support branch from 07be3e9 to 6619a93 Compare August 12, 2021 13:08
@amarekano amarekano force-pushed the extend-spread-element-support branch from e8b1196 to 1ff978c Compare August 31, 2021 09:57
@amarekano
Copy link
Contributor Author

I've removed the Call*WithSpread operations but left the generators and ProgramBuilder API unchanged. I think it's probably best to have multiple generators that use fewer ops in a variety of ways. This imo gives us more flexibilty with code gen and also concise operation set for the AI, mutators, analysers, reducers, etc to work on.

@amarekano
Copy link
Contributor Author

@saelo any thoughts on this one?

guard b.mode != .conservative else { return }
methodName = b.genMethodName()
}
guard let arguments = b.randCallArguments(forMethod: methodName!, on: obj) else { return }
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we don't need b.randCallArguments(forMethod:,on:) here and in the other XWithSpread generators since we will (hopefully) be spreading some of the arguments, in which case the following arguments are anyway at the wrong position (instead, probably just pick 3-5 random variables). Due to that, I think we might anyway only want to run these XWithSpread CodeGenerators if we are not in conservative mode, since we are currently unable to track element types of arrays. So lets put the guard b.mode != .conservative else { return } at the start (and add a short comment in front of it). That will also simplify the first 5 lines of this function, and we can then also drop the b.type(of: arg).Is(.iterable) requirement I think (but then decrease the spread probability, maybe to 0.25?).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -255,6 +255,27 @@ public let CodeGenerators: [CodeGenerator] = [
b.callMethod(methodName!, on: obj, withArgs: arguments)
},

CodeGenerator("MethodCallWithSpreadGenerator", input: .object()) { b, obj in
guard b.mode != .conservative else { return }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a comment here and in the other functions like We cannot currently track element types of Arrays and other Iterable objects and so cannot properly determine argument types when spreading. For that reason, we don't run this CodeGenerator in conservative mode

CodeGenerator("MethodCallWithSpreadGenerator", input: .object()) { b, obj in
guard b.mode != .conservative else { return }

var methodName = b.type(of: obj).randomMethod()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's simplify this here and below to just let methodName = b.type(of: obj).randomMethod() ?? b.genMethodName()

methodName = b.genMethodName()
}

var arguments: [Variable] = []
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thinking about it again, I think we should still try to prefer spreading iterable objects, since attempting to spread most values will lead to exceptions (e.g. TypeError: Found non-callable @@iterator for a simple object). So how about turning lines 267-274, and the same code below, into

var arguments: [Variable] = []
var spreads: [Bool] = []
for _ in 0...Int.random(in: 3...5) {
    let val = b.randVar()
    arguments.append(val)
    // Prefer to spread values that we know are iterable, as non-iterable values will lead to exceptions ("TypeError: Found non-callable @@iterator")
    if b.type(of: val).Is(.iterable) {
        spreads.append(probability(0.9))
    } else {
        spreads.append(probability(0.1))
    }
}

And, since this is I think required 4 times now, WDYT about moving it into a new ProgramBuilder.randCallArgumentsWithSpreading(n: Int) -> (arguments: [Variable], spreads: [Bool]) method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice! I like this approach

@saelo saelo merged commit 590b6b0 into googleprojectzero:main Sep 10, 2021
@saelo
Copy link
Collaborator

saelo commented Sep 10, 2021

Nice, thanks!

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.

None yet

2 participants