WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
167837
[JSC] Align duplicate declaration checks in EvalDeclarationInstantiation with the spec
https://bugs.webkit.org/show_bug.cgi?id=167837
Summary
[JSC] Align duplicate declaration checks in EvalDeclarationInstantiation with...
GSkachkov
Reported
2017-02-04 09:29:52 PST
function goo() { { var error = false; try { let f = 20; eval('var f = 15; eval(" { function f() { }; } ")'); } catch (e) { error = e instanceof SyntaxError; } print(error); // true } print(typeof f); // "undefined" }
Attachments
Patch
(23.82 KB, patch)
2017-07-04 16:01 PDT
,
GSkachkov
no flags
Details
Formatted Diff
Diff
Patch
(25.01 KB, patch)
2017-07-05 13:49 PDT
,
GSkachkov
no flags
Details
Formatted Diff
Diff
Patch
(29.32 KB, patch)
2017-07-08 13:35 PDT
,
GSkachkov
no flags
Details
Formatted Diff
Diff
Patch
(48.09 KB, patch)
2017-07-11 15:40 PDT
,
GSkachkov
no flags
Details
Formatted Diff
Diff
Patch
(41.27 KB, patch)
2017-07-12 01:34 PDT
,
GSkachkov
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from ews121 for ios-simulator-wk2
(7.40 MB, application/zip)
2017-07-12 03:16 PDT
,
Build Bot
no flags
Details
Patch
(41.88 KB, patch)
2017-08-01 03:42 PDT
,
GSkachkov
no flags
Details
Formatted Diff
Diff
Patch
(43.40 KB, patch)
2017-09-09 04:17 PDT
,
GSkachkov
mjs
: review-
Details
Formatted Diff
Diff
Show Obsolete
(7)
View All
Add attachment
proposed patch, testcase, etc.
GSkachkov
Comment 1
2017-06-30 12:46:16 PDT
According to
https://tc39.github.io/ecma262/#sec-evaldeclarationinstantiation
p 5.d.ii.2.a.i and
https://tc39.github.io/ecma262/#sec-functiondeclarationinstantiation
p.9.2.12.29
GSkachkov
Comment 2
2017-07-04 16:01:58 PDT
Created
attachment 314583
[details]
Patch Patch
Saam Barati
Comment 3
2017-07-04 19:29:56 PDT
Comment on
attachment 314583
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314583&action=review
> Source/JavaScriptCore/ChangeLog:8 > + Current patch allow to prevent the redeclaration of let/const variable
This doesn’t look like the right description for what this does. Don’t we already prevent redecoration? I thought this is preventing the hoisting of var over let/const?
> Source/JavaScriptCore/interpreter/Interpreter.cpp:1182 > + // TODO: rename function
What’s this for?
GSkachkov
Comment 4
2017-07-05 13:49:16 PDT
Created
attachment 314651
[details]
Patch Fix comments
GSkachkov
Comment 5
2017-07-05 13:51:56 PDT
Comment on
attachment 314583
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314583&action=review
>> Source/JavaScriptCore/ChangeLog:8 >> + Current patch allow to prevent the redeclaration of let/const variable > > This doesn’t look like the right description for what this does. Don’t we already prevent redecoration? I thought this is preventing the hoisting of var over let/const?
I did for cases when we declare function within eval. Current patch prevent override by var variable. i.e. `(function () { let a; eval('var a') })()` I've updated fix description
>> Source/JavaScriptCore/interpreter/Interpreter.cpp:1182 >> + // TODO: rename function > > What’s this for?
Removed
Saam Barati
Comment 6
2017-07-06 14:01:16 PDT
Comment on
attachment 314651
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314651&action=review
mostly LGTM, just a few questions
> Source/JavaScriptCore/ChangeLog:8 > + Current patch allow to prevent the redeclaration of let/const variable
"allow to prevent" => "prevents"
> Source/JavaScriptCore/interpreter/Interpreter.cpp:1183 > + JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(callFrame, scope, ident);
This name seems slightly off now since you're using this for variables as well as functions. Maybe we can use a name that better describes what it's used for now
> Source/JavaScriptCore/runtime/JSScope.cpp:262 > + return scope->isVarScope() || scope->isCatchScope();
Is it specified behavior to allow var hoisting over catch variable? This seems counter intuitive. And do we want this both for functions and vars?
GSkachkov
Comment 7
2017-07-08 13:35:10 PDT
Created
attachment 314925
[details]
Patch Fixed comments
GSkachkov
Comment 8
2017-07-11 15:40:12 PDT
Created
attachment 315176
[details]
Patch Fix comments
GSkachkov
Comment 9
2017-07-11 15:51:44 PDT
Comment on
attachment 314651
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314651&action=review
>> Source/JavaScriptCore/ChangeLog:8 >> + Current patch allow to prevent the redeclaration of let/const variable > > "allow to prevent" => "prevents"
Fixed
>> Source/JavaScriptCore/interpreter/Interpreter.cpp:1183 >> + JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(callFrame, scope, ident); > > This name seems slightly off now since you're using this for variables as well as functions. Maybe we can use a name that better describes what it's used for now
Renamed to resolveScopeForHoistingVarOrFuncDeclInEval
>> Source/JavaScriptCore/runtime/JSScope.cpp:262 >> + return scope->isVarScope() || scope->isCatchScope(); > > Is it specified behavior to allow var hoisting over catch variable? This seems counter intuitive. And do we want this both for functions and vars?
Oh, you are right It is wrong. We need go up throw catch block the same as 'withScope' for function, but do bind in case of variable
GSkachkov
Comment 10
2017-07-12 01:34:07 PDT
Created
attachment 315215
[details]
Patch New patch
Build Bot
Comment 11
2017-07-12 03:16:02 PDT
Comment hidden (obsolete)
Comment on
attachment 315215
[details]
Patch
Attachment 315215
[details]
did not pass ios-sim-ews (ios-simulator-wk2): Output:
http://webkit-queues.webkit.org/results/4105979
New failing tests: imported/w3c/IndexedDB-private-browsing/idbfactory_open12.html
Build Bot
Comment 12
2017-07-12 03:16:04 PDT
Comment hidden (obsolete)
Created
attachment 315225
[details]
Archive of layout-test-results from ews121 for ios-simulator-wk2 The attached test failures were seen while running run-webkit-tests on the ios-sim-ews. Bot: ews121 Port: ios-simulator-wk2 Platform: Mac OS X 10.12.5
Saam Barati
Comment 13
2017-07-25 23:24:51 PDT
Comment on
attachment 315215
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=315215&action=review
> Source/JavaScriptCore/ChangeLog:8 > + Current patch allows prevent the redeclaration of let/const variable
allows prevent => prevents
> Source/JavaScriptCore/ChangeLog:15 > + outside of eval or within eval but if top level function declared i.e: > + ``` > + { > + let foo; > + eval('function foo(){}'); > + }
I'm confused about your wording here. What happens in this example?
> Source/JavaScriptCore/ChangeLog:28 > + to higher var scope. This case is present by following bugs:
What do you mean by "case is present" here?
> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2502 > +ResolveType BytecodeGenerator::resolveType(bool doHoistInEval)
I'm not a fan of adding this parameter here. It seems like your branch on the value is wrong, it should just be the first branch in this function, since we always want it to be dynamic if doHoistInEval is true. I sort of think it'd be cleaner if you didn't override the existing BytecodeGenerator::putToScope(.) function, and just defined your own special put_to_scope that just did exactly what you need for this special hoisting use case.
> Source/JavaScriptCore/interpreter/Interpreter.cpp:1208 > + JSValue resolvedScope = JSScope::resolveScopeForHoistingVarOrFuncDeclInEval(callFrame, scope, function->name());
style nit: Indentation looks wrong here, but maybe it's just bugzilla.
> Source/JavaScriptCore/interpreter/Interpreter.cpp:1211 > + if (!variableObject->hasProperty(callFrame, function->name().impl())) {
Don't you need an exception check here? Or maybe just assert that there isn't one if it's not possible since hasProperty might throw in the general case. Also, on a more general note, why is this needed? What was wrong with the previous code?
GSkachkov
Comment 14
2017-08-01 03:42:14 PDT
Created
attachment 316839
[details]
Patch Fix comments
Saam Barati
Comment 15
2017-08-29 14:47:05 PDT
Comment on
attachment 316839
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316839&action=review
> Source/JavaScriptCore/ChangeLog:8 > + Current patch prevent the redeclaration of let/const variable
prevent => prevents
> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:137 > + RefPtr<RegisterID> topLevelObjectScope = doHoistInEval > + ? emitResolveScopeForHoistingFuncDeclInEval(nullptr, metadata->ident())
Will this always resolve to the same scope for every single eval variable?
> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2642 > + ResolveType type = resolveType();
style: extra space before "="
> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2670 > + instructions().append(!!offset ? offset.offset() : 0);
offset is a constant above, what is this supposed to be doing?
GSkachkov
Comment 16
2017-09-05 12:44:31 PDT
Comment on
attachment 316839
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316839&action=review
>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:137 >> + ? emitResolveScopeForHoistingFuncDeclInEval(nullptr, metadata->ident()) > > Will this always resolve to the same scope for every single eval variable?
Yeah, I'm expecting that they all should be bound to same var scope: ``` function f() { var foo; try { let boo; eval('function foo(){} function boo() {}'); } catch (e) { print(e); } print(typeof foo === 'function'); print(typeof boo==='function'); } ``` Binding to different scope from var scope, should be prevented by SyntaxErorr Interpreter.cpp. But I'll double check in spec how following code should behave, I mean check if there should be: true false or false false With my patch JSC returns false-false, but Chrome (true-false) and Firefox(false-false) behave in different way.
>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2642 >> + ResolveType type = resolveType(); > > style: extra space before "="
Fixed
>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2670 >> + instructions().append(!!offset ? offset.offset() : 0); > > offset is a constant above, what is this supposed to be doing?
Ohh, You are right, this condition is unnecessary.
GSkachkov
Comment 17
2017-09-09 04:17:14 PDT
Created
attachment 320341
[details]
Patch Patch
Saam Barati
Comment 18
2017-10-04 12:11:07 PDT
Comment on
attachment 320341
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=320341&action=review
> Source/JavaScriptCore/ChangeLog:32 > + try { > + let boo2; > + eval('function foo(){} function boo() {}');
Why would this throw here?
> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2678 > + // put_to_scope scope, id, value, GetPutInfo, Structure, Operand
This comment doesn't match what you're emitting below.
> Source/JavaScriptCore/interpreter/Interpreter.cpp:1186 > + if (!eval->isStrictMode()) { > + JSValue resolvedScope = JSScope::resolveScopeForHoistingVarOrFuncDeclInEval(callFrame, scope, ident); > + if (resolvedScope.isUndefined()) > + return checkedReturn(throwSyntaxError(callFrame, throwScope, makeString("Cannot declare a var variable that shadows a let/const/class variable: '", String(ident.impl()), "'"))); > + }
Doesn't the spec say we need to check that none of these would throw before storing any of them into the actual scope object?
Maciej Stachowiak
Comment 19
2020-05-30 19:46:08 PDT
Comment on
attachment 320341
[details]
Patch Good to make this correct, but unfortunately this patch no longer applies.
Radar WebKit Bug Importer
Comment 20
2023-06-26 07:55:59 PDT
<
rdar://problem/111328974
>
Alexey Shvayka
Comment 21
2023-06-26 07:59:43 PDT
Pull request:
https://github.com/WebKit/WebKit/pull/15294
EWS
Comment 22
2023-06-29 03:01:01 PDT
Committed
265614@main
(d0d05739899c): <
https://commits.webkit.org/265614@main
> Reviewed commits have been landed. Closing PR #15294 and removing active labels.
Alexey Shvayka
Comment 23
2023-06-29 14:21:37 PDT
***
Bug 168184
has been marked as a duplicate of this bug. ***
WebKit Commit Bot
Comment 24
2023-07-10 13:41:30 PDT
Re-opened since this is blocked by
bug 259070
Alexey Shvayka
Comment 25
2023-07-18 07:56:34 PDT
Comment hidden (obsolete)
I'm still investigating the snippet we were crashing on, and it's super weird why eval(` try { function foo() {} eval('try { function foo() {}; print("ok") } catch {} function foo() {}'); } catch {} `); and eval(` if (true) { function foo() {} eval('if (true) { function foo() {}; print("ok") } function foo() {}'); } `); have different semantics in V8 / SM.
Alexey Shvayka
Comment 26
2023-07-18 08:05:13 PDT
Comment hidden (obsolete)
(In reply to Alexey Shvayka from
comment #25
)
> I'm still investigating the snippet we were crashing on, and it's super > weird why
Oh the first snippet "swallows" the SyntaxError from eval(), hence the perceived difference.
Alexey Shvayka
Comment 27
2023-07-21 12:45:44 PDT
Pull request:
https://github.com/WebKit/WebKit/pull/15996
EWS
Comment 28
2023-07-22 07:01:11 PDT
Committed
266229@main
(ab0917349c9f): <
https://commits.webkit.org/266229@main
> Reviewed commits have been landed. Closing PR #15996 and removing active labels.
Alexey Shvayka
Comment 29
2023-07-24 07:13:12 PDT
***
Bug 258507
has been marked as a duplicate of this bug. ***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug