Skip to content

Commit fd69080

Browse files
Use builtin @@hasInstance from prototype in instanceOf (chakra-core#6861)
* Don't ignore build-in hasInstance (from prototype) - removing invalid optimisation * Remove `IsES6HasInstanceEnabled` switch Fixes chakra-core#6507
1 parent a9850e2 commit fd69080

File tree

6 files changed

+62
-50
lines changed

6 files changed

+62
-50
lines changed

lib/Common/ConfigFlagsList.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
3-
// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
44
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
55
//-------------------------------------------------------------------------------------------------------
66

@@ -695,7 +695,6 @@ PHASE(All)
695695
#else
696696
#define DEFAULT_CONFIG_ES6RegExSymbols (false)
697697
#endif
698-
#define DEFAULT_CONFIG_ES6HasInstance (true)
699698
#define DEFAULT_CONFIG_ES7AsyncAwait (true)
700699
#define DEFAULT_CONFIG_ES7ExponentionOperator (true)
701700
#define DEFAULT_CONFIG_ES7TrailingComma (true)
@@ -1180,7 +1179,6 @@ FLAGPR_REGOVR_EXP(Boolean, ES6, ES6RegExPrototypeProperties, "Enable ES6 propert
11801179
// Also, the corresponding helpers in JnHelperMethodList.h should be marked as being reentrant
11811180
FLAGPR_REGOVR_EXP(Boolean, ES6, ES6RegExSymbols , "Enable ES6 RegExp symbols" , DEFAULT_CONFIG_ES6RegExSymbols)
11821181

1183-
FLAGPR (Boolean, ES6, ES6HasInstance , "Enable ES6 @@hasInstance symbol" , DEFAULT_CONFIG_ES6HasInstance)
11841182
FLAGPR (Boolean, ES6, ES6Verbose , "Enable ES6 verbose trace" , DEFAULT_CONFIG_ES6Verbose)
11851183
FLAGPR (Boolean, ES6, ESObjectGetOwnPropertyDescriptors, "Enable Object.getOwnPropertyDescriptors" , DEFAULT_CONFIG_ESObjectGetOwnPropertyDescriptors)
11861184

lib/Runtime/Base/ThreadConfigFlagsList.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
3-
// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
44
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
55
//-------------------------------------------------------------------------------------------------------
66

@@ -35,7 +35,6 @@ FLAG_RELEASE(IsES6RegExStickyEnabled, ES6RegExSticky)
3535
FLAG_RELEASE(IsES2018RegExDotAllEnabled, ES2018RegExDotAll)
3636
FLAG_RELEASE(IsES6RegExPrototypePropertiesEnabled, ES6RegExPrototypeProperties)
3737
FLAG_RELEASE(IsES6RegExSymbolsEnabled, ES6RegExSymbols)
38-
FLAG_RELEASE(IsES6HasInstanceEnabled, ES6HasInstance)
3938
FLAG_RELEASE(SkipSplitOnNoResult, SkipSplitOnNoResult)
4039
FLAG_RELEASE(IsES7AsyncAndAwaitEnabled, ES7AsyncAwait)
4140
FLAG_RELEASE(IsESObjectGetOwnPropertyDescriptorsEnabled, ESObjectGetOwnPropertyDescriptors)

lib/Runtime/Language/JavascriptOperators.cpp

+24-32
Original file line numberDiff line numberDiff line change
@@ -7716,45 +7716,37 @@ using namespace Js;
77167716
}
77177717

77187718
RecyclableObject* constructor = VarTo<RecyclableObject>(aClass);
7719-
if (scriptContext->GetConfig()->IsES6HasInstanceEnabled())
7719+
if (VarIs<JavascriptFunction>(constructor))
77207720
{
7721-
if (VarIs<JavascriptFunction>(constructor))
7721+
JavascriptFunction* func = VarTo<JavascriptFunction>(constructor);
7722+
if (func->IsBoundFunction())
77227723
{
7723-
JavascriptFunction* func = VarTo<JavascriptFunction>(constructor);
7724-
if (func->IsBoundFunction())
7725-
{
7726-
BoundFunction* boundFunc = (BoundFunction*)func;
7727-
constructor = boundFunc->GetTargetFunction();
7728-
}
7724+
BoundFunction* boundFunc = (BoundFunction*)func;
7725+
constructor = boundFunc->GetTargetFunction();
77297726
}
7730-
7731-
Var instOfHandler = JavascriptOperators::GetPropertyNoCache(constructor,
7732-
PropertyIds::_symbolHasInstance, scriptContext);
7733-
if (JavascriptOperators::IsUndefinedObject(instOfHandler)
7734-
|| instOfHandler == scriptContext->GetBuiltInLibraryFunction(JavascriptFunction::EntryInfo::SymbolHasInstance.GetOriginalEntryPoint()))
7727+
}
7728+
7729+
Var instOfHandler = JavascriptOperators::GetPropertyNoCache(constructor,
7730+
PropertyIds::_symbolHasInstance, scriptContext);
7731+
if (JavascriptOperators::IsUndefinedObject(instOfHandler))
7732+
{
7733+
return JavascriptBoolean::ToVar(constructor->HasInstance(instance, scriptContext, inlineCache), scriptContext);
7734+
}
7735+
else
7736+
{
7737+
if (!JavascriptConversion::IsCallable(instOfHandler))
77357738
{
7736-
return JavascriptBoolean::ToVar(constructor->HasInstance(instance, scriptContext, inlineCache), scriptContext);
7739+
JavascriptError::ThrowTypeError(scriptContext, JSERR_Property_NeedFunction, _u("Symbol[Symbol.hasInstance]"));
77377740
}
7738-
else
7739-
{
7740-
if (!JavascriptConversion::IsCallable(instOfHandler))
7741-
{
7742-
JavascriptError::ThrowTypeError(scriptContext, JSERR_Property_NeedFunction, _u("Symbol[Symbol.hasInstance]"));
7743-
}
77447741

7745-
ThreadContext * threadContext = scriptContext->GetThreadContext();
7746-
RecyclableObject *instFunc = VarTo<RecyclableObject>(instOfHandler);
7747-
Var result = threadContext->ExecuteImplicitCall(instFunc, ImplicitCall_Accessor, [=]()->Js::Var
7748-
{
7749-
return CALL_FUNCTION(scriptContext->GetThreadContext(), instFunc, CallInfo(CallFlags_Value, 2), constructor, instance);
7750-
});
7742+
ThreadContext * threadContext = scriptContext->GetThreadContext();
7743+
RecyclableObject *instFunc = VarTo<RecyclableObject>(instOfHandler);
7744+
Var result = threadContext->ExecuteImplicitCall(instFunc, ImplicitCall_Accessor, [=]()->Js::Var
7745+
{
7746+
return CALL_FUNCTION(scriptContext->GetThreadContext(), instFunc, CallInfo(CallFlags_Value, 2), constructor, instance);
7747+
});
77517748

7752-
return JavascriptBoolean::ToVar(JavascriptConversion::ToBoolean(result, scriptContext) ? TRUE : FALSE, scriptContext);
7753-
}
7754-
}
7755-
else
7756-
{
7757-
return JavascriptBoolean::ToVar(constructor->HasInstance(instance, scriptContext, inlineCache), scriptContext);
7749+
return JavascriptBoolean::ToVar(JavascriptConversion::ToBoolean(result, scriptContext) ? TRUE : FALSE, scriptContext);
77587750
}
77597751
JIT_HELPER_END(ScrObj_OP_IsInst);
77607752
}

lib/Runtime/Library/JavascriptLibrary.cpp

+7-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
3-
// Copyright (c) 2022 ChakraCore Project Contributors. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
44
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
55
//-------------------------------------------------------------------------------------------------------
66

@@ -2599,10 +2599,7 @@ namespace Js
25992599
library->AddMember(symbolConstructor, PropertyIds::length, TaggedInt::ToVarUnchecked(0), PropertyConfigurable);
26002600
library->AddMember(symbolConstructor, PropertyIds::prototype, library->symbolPrototype, PropertyNone);
26012601
library->AddMember(symbolConstructor, PropertyIds::name, scriptContext->GetPropertyString(PropertyIds::Symbol), PropertyConfigurable);
2602-
if (scriptContext->GetConfig()->IsES6HasInstanceEnabled())
2603-
{
2604-
library->AddMember(symbolConstructor, PropertyIds::hasInstance, library->GetSymbolHasInstance(), PropertyNone);
2605-
}
2602+
library->AddMember(symbolConstructor, PropertyIds::hasInstance, library->GetSymbolHasInstance(), PropertyNone);
26062603
if (scriptContext->GetConfig()->IsES6IsConcatSpreadableEnabled())
26072604
{
26082605
library->AddMember(symbolConstructor, PropertyIds::isConcatSpreadable, library->GetSymbolIsConcatSpreadable(), PropertyNone);
@@ -3197,14 +3194,11 @@ namespace Js
31973194
builtinFuncs[BuiltinFunction::JavascriptFunction_Call] = func;
31983195
library->AddFunctionToLibraryObject(functionPrototype, PropertyIds::toString, &JavascriptFunction::EntryInfo::ToString, 0);
31993196

3200-
if (scriptContext->GetConfig()->IsES6HasInstanceEnabled())
3201-
{
3202-
scriptContext->SetBuiltInLibraryFunction(JavascriptFunction::EntryInfo::SymbolHasInstance.GetOriginalEntryPoint(),
3203-
library->AddFunctionToLibraryObjectWithName(functionPrototype, PropertyIds::_symbolHasInstance, PropertyIds::_RuntimeFunctionNameId_hasInstance,
3204-
&JavascriptFunction::EntryInfo::SymbolHasInstance, 1));
3205-
functionPrototype->SetWritable(PropertyIds::_symbolHasInstance, false);
3206-
functionPrototype->SetConfigurable(PropertyIds::_symbolHasInstance, false);
3207-
}
3197+
scriptContext->SetBuiltInLibraryFunction(JavascriptFunction::EntryInfo::SymbolHasInstance.GetOriginalEntryPoint(),
3198+
library->AddFunctionToLibraryObjectWithName(functionPrototype, PropertyIds::_symbolHasInstance, PropertyIds::_RuntimeFunctionNameId_hasInstance,
3199+
&JavascriptFunction::EntryInfo::SymbolHasInstance, 1));
3200+
functionPrototype->SetWritable(PropertyIds::_symbolHasInstance, false);
3201+
functionPrototype->SetConfigurable(PropertyIds::_symbolHasInstance, false);
32083202

32093203
functionPrototype->DynamicObject::SetAccessors(PropertyIds::caller, library->throwTypeErrorRestrictedPropertyAccessorFunction, library->throwTypeErrorRestrictedPropertyAccessorFunction);
32103204
functionPrototype->SetEnumerable(PropertyIds::caller, false);

test/es6/instanceOfProto.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
4+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
5+
//-------------------------------------------------------------------------------------------------------
6+
7+
// @ts-check
8+
/// <reference path="..\UnitTestFramework\UnitTestFramework.js" />
9+
WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
10+
11+
const tests = [
12+
{
13+
name: "Issue #6507 : Use @@hasInstance of built-in prototype",
14+
body() {
15+
const obj = { __proto__: String };
16+
const testFn = () => "hello" instanceof obj;
17+
assert.doesNotThrow(testFn, "instanceof should not throw");
18+
assert.areEqual(false, testFn(), "instanceof should return false");
19+
}
20+
}
21+
]
22+
23+
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

test/es6/rlexe.xml

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<regress-exe>
3+
<test>
4+
<default>
5+
<files>instanceOfProto.js</files>
6+
<compile-flags>-args summary -endargs</compile-flags>
7+
</default>
8+
</test>
39
<test>
410
<default>
511
<files>bug_issue_2747.js</files>

0 commit comments

Comments
 (0)