Bug 160553 - [ES6] Module namespace object should not allow unset IC
Summary: [ES6] Module namespace object should not allow unset IC
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-04 09:41 PDT by Yusuke Suzuki
Modified: 2016-08-07 19:50 PDT (History)
5 users (show)

See Also:


Attachments
Patch (22.45 KB, patch)
2016-08-04 10:05 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (22.62 KB, patch)
2016-08-04 23:06 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2016-08-04 09:41:19 PDT
[ES6] Namespace object should not allow IC
Comment 1 Yusuke Suzuki 2016-08-04 10:05:20 PDT
Created attachment 285334 [details]
Patch
Comment 2 Yusuke Suzuki 2016-08-04 10:17:13 PDT
Comment on attachment 285334 [details]
Patch

I'll do a slight change.
Comment 3 Yusuke Suzuki 2016-08-04 23:06:19 PDT
Created attachment 285402 [details]
Patch
Comment 4 Saam Barati 2016-08-05 16:25:19 PDT
Comment on attachment 285402 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=285402&action=review

> Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp:132
> +        JSModuleRecord::Resolution resolution = moduleRecord->resolveExport(exec, Identifier::fromUid(exec, propertyName.uid()));
> +        ASSERT(resolution.type != JSModuleRecord::Resolution::Type::NotFound && resolution.type != JSModuleRecord::Resolution::Type::Ambiguous);
> +
> +        JSModuleRecord* targetModule = resolution.moduleRecord;
> +        JSModuleEnvironment* targetEnvironment = targetModule->moduleEnvironment();
> +
> +        PropertySlot trampolineSlot(targetEnvironment, PropertySlot::InternalMethodType::Get);
> +        bool found = targetEnvironment->methodTable(exec->vm())->getOwnPropertySlot(targetEnvironment, exec, resolution.localName, trampolineSlot);
> +        ASSERT_UNUSED(found, found);

Why do these assertions have to hold?
I haven't thought too hard, but can't you just call GetOwnProperty on a namespace object and have this not actually be resolved?
like:
`
import * as ns from ...;
Reflect.getOwnPropertyDescriptor(ns, someIdentNotInNS)
`
Comment 5 Yusuke Suzuki 2016-08-05 23:33:58 PDT
Comment on attachment 285402 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=285402&action=review

>> Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp:132
>> +        ASSERT_UNUSED(found, found);
> 
> Why do these assertions have to hold?
> I haven't thought too hard, but can't you just call GetOwnProperty on a namespace object and have this not actually be resolved?
> like:
> `
> import * as ns from ...;
> Reflect.getOwnPropertyDescriptor(ns, someIdentNotInNS)
> `

The above example does not reach here because we filter them by

`
if (!thisObject->m_exports.contains(propertyName.uid()))
    return false;
`
in L116.
Comment 6 Yusuke Suzuki 2016-08-06 11:50:02 PDT
Comment on attachment 285402 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=285402&action=review

>>> Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp:132
>>> +        ASSERT_UNUSED(found, found);
>> 
>> Why do these assertions have to hold?
>> I haven't thought too hard, but can't you just call GetOwnProperty on a namespace object and have this not actually be resolved?
>> like:
>> `
>> import * as ns from ...;
>> Reflect.getOwnPropertyDescriptor(ns, someIdentNotInNS)
>> `
> 
> The above example does not reach here because we filter them by
> 
> `
> if (!thisObject->m_exports.contains(propertyName.uid()))
>     return false;
> `
> in L116.

And this m_exports is collected by JSModuleRecord.cpp's getExportedNames, and already validated by JSModuleRecord::getModuleNamespace.
As a result, this m_exports only contains the names that can be resolved. And when the name is resolved, the resolution always has the target module and the local name.
So looking up the local binding from the target module always succeed.
Comment 7 Saam Barati 2016-08-07 14:06:36 PDT
Comment on attachment 285402 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=285402&action=review

r=me

>>>> Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp:132
>>>> +        ASSERT_UNUSED(found, found);
>>> 
>>> Why do these assertions have to hold?
>>> I haven't thought too hard, but can't you just call GetOwnProperty on a namespace object and have this not actually be resolved?
>>> like:
>>> `
>>> import * as ns from ...;
>>> Reflect.getOwnPropertyDescriptor(ns, someIdentNotInNS)
>>> `
>> 
>> The above example does not reach here because we filter them by
>> 
>> `
>> if (!thisObject->m_exports.contains(propertyName.uid()))
>>     return false;
>> `
>> in L116.
> 
> And this m_exports is collected by JSModuleRecord.cpp's getExportedNames, and already validated by JSModuleRecord::getModuleNamespace.
> As a result, this m_exports only contains the names that can be resolved. And when the name is resolved, the resolution always has the target module and the local name.
> So looking up the local binding from the target module always succeed.

Makes sense.
Comment 8 Yusuke Suzuki 2016-08-07 19:29:39 PDT
Comment on attachment 285402 [details]
Patch

Thanks!
Comment 9 WebKit Commit Bot 2016-08-07 19:50:23 PDT
Comment on attachment 285402 [details]
Patch

Clearing flags on attachment: 285402

Committed r204248: <http://trac.webkit.org/changeset/204248>
Comment 10 WebKit Commit Bot 2016-08-07 19:50:26 PDT
All reviewed patches have been landed.  Closing bug.