Skip to content

Commit 0c6561c

Browse files
authored
Fix JsIsCallable (#6727)
Fix JsIsCallable JSRT API function which was giving a false-positive when it was called on a class function (e.g. class _ { }). Also add tests for JsIsCallable and JsIsConstructor, which were missing. Closes #6720
1 parent b0b23aa commit 0c6561c

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

bin/NativeTests/JsRTApiTest.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#include "stdafx.h"
@@ -2259,7 +2260,70 @@ namespace JsRTApiTest
22592260
TEST_CASE("ApiTest_ModuleSuccessTest", "[ApiTest]")
22602261
{
22612262
JsRTApiTest::WithSetup(JsRuntimeAttributeEnableExperimentalFeatures, ModuleSuccessTest);
2263+
}
2264+
2265+
void JsIsCallableTest(JsRuntimeAttributes attributes, JsRuntimeHandle runtime)
2266+
{
2267+
JsValueRef callables, callable, index, nonCallables, nonCallable;
2268+
bool check;
2269+
2270+
REQUIRE(JsRunScript(_u("[function(){},function*(){},async function(){},async function*(){},_=>_,async _=>_]"),
2271+
JS_SOURCE_CONTEXT_NONE, _u(""), &callables) == JsNoError);
2272+
2273+
for (int i = 0; i < 6; i++)
2274+
{
2275+
REQUIRE(JsIntToNumber(i, &index) == JsNoError);
2276+
REQUIRE(JsGetIndexedProperty(callables, index, &callable) == JsNoError);
2277+
REQUIRE(JsIsCallable(callable, &check) == JsNoError);
2278+
CHECK(check);
2279+
}
2280+
2281+
2282+
REQUIRE(JsRunScript(_u("[class{},Math,Reflect,{}]"), JS_SOURCE_CONTEXT_NONE, _u(""), &nonCallables) == JsNoError);
2283+
2284+
for (int i = 0; i < 4; i++)
2285+
{
2286+
REQUIRE(JsIntToNumber(i, &index) == JsNoError);
2287+
REQUIRE(JsGetIndexedProperty(nonCallables, index, &nonCallable) == JsNoError);
2288+
REQUIRE(JsIsCallable(nonCallable, &check) == JsNoError);
2289+
CHECK(!check);
2290+
}
2291+
}
2292+
2293+
TEST_CASE("ApiTest_JsIsCallableTest", "[ApiTest]") {
2294+
JsRTApiTest::RunWithAttributes(JsIsCallableTest);
2295+
}
2296+
2297+
void JsIsConstructorTest(JsRuntimeAttributes attributes, JsRuntimeHandle runtime)
2298+
{
2299+
JsValueRef constructables, constructable, index, nonConstructables, nonConstructable;
2300+
bool check;
2301+
2302+
REQUIRE(JsRunScript(_u("[class{},function(){}]"), JS_SOURCE_CONTEXT_NONE, _u(""), &constructables) == JsNoError);
2303+
2304+
for (int i = 0; i < 2; i++)
2305+
{
2306+
REQUIRE(JsIntToNumber(i, &index) == JsNoError);
2307+
REQUIRE(JsGetIndexedProperty(constructables, index, &constructable) == JsNoError);
2308+
REQUIRE(JsIsConstructor(constructable, &check) == JsNoError);
2309+
CHECK(check);
2310+
}
2311+
2312+
2313+
REQUIRE(JsRunScript(_u("[Math,Reflect,{},function*(){},async function(){},async function*(){},_=>_,async _=>_]"),
2314+
JS_SOURCE_CONTEXT_NONE, _u(""), &nonConstructables) == JsNoError);
2315+
2316+
for (int i = 0; i < 8; i++)
2317+
{
2318+
REQUIRE(JsIntToNumber(i, &index) == JsNoError);
2319+
REQUIRE(JsGetIndexedProperty(nonConstructables, index, &nonConstructable) == JsNoError);
2320+
REQUIRE(JsIsConstructor(nonConstructable, &check) == JsNoError);
2321+
CHECK(!check);
2322+
}
2323+
}
22622324

2325+
TEST_CASE("ApiTest_JsIsConstructorTest", "[ApiTest]") {
2326+
JsRTApiTest::RunWithAttributes(JsIsConstructorTest);
22632327
}
22642328

22652329
void SetModuleHostInfoTest(JsRuntimeAttributes attributes, JsRuntimeHandle runtime)

lib/Jsrt/Core/JsrtCore.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#include "JsrtPch.h"
@@ -1460,7 +1461,7 @@ CHAKRA_API JsIsCallable(_In_ JsValueRef object, _Out_ bool *isCallable)
14601461
VALIDATE_INCOMING_OBJECT(object, scriptContext);
14611462
PARAM_NOT_NULL(isCallable);
14621463

1463-
*isCallable = Js::JavascriptConversion::IsCallable(object);
1464+
*isCallable = Js::JavascriptConversion::IsCallable(object) && !Js::JavascriptOperators::IsClassConstructor(object);
14641465

14651466
return JsNoError;
14661467
});

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7290,7 +7290,7 @@ using namespace Js;
72907290
{
72917291
JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Op_IsClassConstructor);
72927292
JavascriptFunction * function = JavascriptOperators::TryFromVar<JavascriptFunction>(instance);
7293-
return function && (function->GetFunctionInfo()->IsClassConstructor() || (!function->IsScriptFunction() && !function->IsExternalFunction()));
7293+
return function && function->GetFunctionInfo()->IsClassConstructor();
72947294
JIT_HELPER_END(Op_IsClassConstructor);
72957295
}
72967296

0 commit comments

Comments
 (0)