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 Function.prototype.call #805

Merged
merged 3 commits into from Oct 6, 2020

Conversation

RageKnify
Copy link
Member

This Pull Request fixes/closes #797.
It changes the following:

-Implement Function.prototype.call
-Add a test to ensure it works

@codecov
Copy link

codecov bot commented Oct 5, 2020

Codecov Report

Merging #805 into master will increase coverage by 0.04%.
The diff coverage is 63.63%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #805      +/-   ##
==========================================
+ Coverage   59.62%   59.67%   +0.04%     
==========================================
  Files         155      155              
  Lines        9964     9973       +9     
==========================================
+ Hits         5941     5951      +10     
+ Misses       4023     4022       -1     
Impacted Files Coverage Δ
boa/src/builtins/regexp/mod.rs 70.25% <25.00%> (-0.91%) ⬇️
boa/src/builtins/function/mod.rs 63.80% <85.71%> (+1.56%) ⬆️
boa/src/builtins/object/mod.rs 61.05% <0.00%> (+2.10%) ⬆️
boa/src/value/display.rs 88.63% <0.00%> (+2.27%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ff25a8a...2646951. Read the comment docs.

@RageKnify
Copy link
Member Author

Forgot to end the error message and write a test for it, I'm doing it right now.

@HalidOdat HalidOdat added builtins PRs and Issues related to builtins/intrinsics enhancement New feature or request labels Oct 5, 2020
@HalidOdat HalidOdat added this to the v0.11.0 milestone Oct 5, 2020
boa/src/builtins/function/mod.rs Outdated Show resolved Hide resolved
boa/src/builtins/function/mod.rs Outdated Show resolved Hide resolved
boa/src/builtins/function/mod.rs Outdated Show resolved Hide resolved
boa/src/builtins/function/mod.rs Outdated Show resolved Hide resolved
@HalidOdat HalidOdat changed the title Feat: Function.prototype.call Feature Function.prototype.call Oct 5, 2020
@HalidOdat
Copy link
Member

Maybe we should test it with more that one argumet

@RageKnify
Copy link
Member Author

Maybe we should test it with more that one argumet

Reasonable, any idea for a function to test?

@HalidOdat
Copy link
Member

Reasonable, any idea for a function to test?

We can test any function that takes 1 or more arumunts ( not including this ), how about Number.prototype.toString( [radix] ) it takes an optional base we can make the base 16 and assert that the number is in hexadecimal notation.

@RageKnify
Copy link
Member Author

I came up with:

function f(a, b){
this.a = a;
this.b = b;
}
let o = {a: 0, b: 0}
f.call(o, 1, 2)

Then we check o.a == 1 and o.b == 2, what do you think @HalidOdat ?

@HalidOdat
Copy link
Member

Then we check o.a == 1 and o.b == 2, what do you think @HalidOdat ?

Yes. This looks good :)

Copy link
Member

@HalidOdat HalidOdat left a comment

Choose a reason for hiding this comment

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

Looks perfect to me!

Copy link
Member

@Razican Razican left a comment

Choose a reason for hiding this comment

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

Looks good to me too :D

@Razican Razican merged commit b027a76 into boa-dev:master Oct 6, 2020
@RageKnify RageKnify deleted the feat/function_call branch October 6, 2020 15:52
@Razican
Copy link
Member

Razican commented Oct 6, 2020

Somehow it seems we didn't see that this was failing the test262 suite. I think we should revert it until we find the issue. What do you think @HalidOdat @RageKnify ?

return context.throw_type_error(format!("{} is not a function", this.display()));
}
let this_arg: Value = args.get(0).cloned().unwrap_or_default();
// TODO?: 3. Perform PrepareForTailCall
Copy link
Member

Choose a reason for hiding this comment

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

I think it maybe the missing // TODO?: 3. Perform PrepareForTailCall.

@HalidOdat
Copy link
Member

HalidOdat commented Oct 6, 2020

I think we should revert it until we find the issue. What do you think @HalidOdat @RageKnify ?

Yes. I think so too.

EDIT: Or we can comment it out. with a todo, and ignore the tests

@RageKnify
Copy link
Member Author

I'd like to identify which test of test262 is causing the failure. But I'm assuming its a long recursion that requires TailCall optimization, not sure how boa would handle that...

@Razican
Copy link
Member

Razican commented Oct 7, 2020

I'd like to identify which test of test262 is causing the failure. But I'm assuming its a long recursion that requires TailCall optimization, not sure how boa would handle that...

Something that can be done to see the last test to be executed is to uncomment this line locally and run it like this.

The error message was this:

memory allocation of 51539607528 bytes failed/home/runner/work/_temp/445e69cc-9b3d-4bcd-887f-44df8e8c1c9b.sh: line 2:  3393 Aborted                 (core dumped) cargo run --release --bin boa_tester -- -o ../gh-pages/test262

In any case, if it can't be fixed easily, we should revert this until we get a proper fix, we can't have the CI and the test262 results failing on every commit.

@RageKnify
Copy link
Member Author

RageKnify commented Oct 7, 2020

I've identified the test, test/built-ins/Array/prototype/map/15.4.4.19-3-28.js:

// Copyright (c) 2012 Ecma International.  All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-array.prototype.map
description: Array.prototype.map - value of 'length' is boundary value (2^32)
---*/

function callbackfn(val, idx, obj) {
  return val > 10;
}

var obj = {
  0: 12,
  length: 4294967296
};
assert.throws(RangeError, function() {
  var newArr = Array.prototype.map.call(obj, callbackfn);
});

I don't think the problem is recursion, it is Array.prototype.map not being spec compliant, it's trying to create a huge Vec and dies.
https://tc39.es/ecma262/#sec-array.prototype.map
~~Point 6.c (HasProperty(O, Pk)) isn't respected in:

let values: Vec<Value> = (0..length)
.map(|idx| {
let element = this.get_field(idx);
let args = [element, Value::from(idx), new.clone()];
interpreter
.call(&callback, &this_val, &args)
.unwrap_or_else(|_| Value::undefined())
})
.collect();

~~The fix doesn't seem too complicated.

PS: I'm busy right now but I hope to get it fixed in the next 6 hours.~~

PPS: Testing the same code on Chrome the problem in the JS code seems to be that 4294967296 is 2^32, which results in RangeError: Invalid array length

So following the spec the calls should be Array.prototype.map -> ArraySpeciesCreate(O, len) -> ArrayCreate(len) and ArrayCreate has: 3. If length > 2^32 - 1, throw a RangeError exception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
builtins PRs and Issues related to builtins/intrinsics enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement Function.prototype.call
3 participants