Skip to content

Commit c523fea

Browse files
committed
Don't mess with the function name/displayname for __chakraLibrary functions, and allow __chakraLibrary functions to be constructors
1 parent 76275c2 commit c523fea

File tree

2 files changed

+46
-37
lines changed

2 files changed

+46
-37
lines changed

lib/Runtime/Library/EngineInterfaceObject.cpp

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -272,21 +272,6 @@ namespace Js
272272
{
273273
ScriptContext *scriptContext = scriptFunction->GetScriptContext();
274274

275-
// Use GetSz rather than GetString because we use wcsrchr below, which expects a null-terminated string
276-
// Callers can pass in a string like "get compare" or "Intl.Collator.prototype.resolvedOptions" -- only for the
277-
// latter do we extract a shortName.
278-
const char16 *methodNameBuf = displayName->GetSz();
279-
charcount_t methodNameLength = displayName->GetLength();
280-
const char16 *shortName = wcsrchr(methodNameBuf, _u('.'));
281-
charcount_t shortNameOffset = 0;
282-
if (shortName != nullptr)
283-
{
284-
shortName++;
285-
shortNameOffset = static_cast<charcount_t>(shortName - methodNameBuf);
286-
}
287-
288-
scriptFunction->GetFunctionProxy()->EnsureDeserialized()->SetDisplayName(methodNameBuf, methodNameLength, shortNameOffset);
289-
290275
if (!isConstructor)
291276
{
292277
// set the ErrorOnNew attribute to disallow construction. JsBuiltIn/Intl functions are usually regular ScriptFunctions
@@ -308,29 +293,49 @@ namespace Js
308293
AssertMsg((scriptFunction->GetFunctionInfo()->GetAttributes() & FunctionInfo::Attributes::ErrorOnNew) == 0, "Why is the function not constructable by default?");
309294
}
310295

311-
// handle the name property AFTER handling isConstructor, because this can initialize the function's deferred type
312-
Var existingName = nullptr;
313-
if (JavascriptOperators::GetOwnProperty(scriptFunction, PropertyIds::name, &existingName, scriptContext, nullptr))
296+
if (isPublic)
314297
{
315-
JavascriptString *existingNameString = JavascriptString::FromVar(existingName);
316-
if (existingNameString->GetLength() == 0)
298+
// Use GetSz rather than GetString because we use wcsrchr below, which expects a null-terminated string
299+
// Callers can pass in a string like "get compare" or "Intl.Collator.prototype.resolvedOptions" -- only for the
300+
// latter do we extract a shortName.
301+
const char16 *methodNameBuf = displayName->GetSz();
302+
charcount_t methodNameLength = displayName->GetLength();
303+
const char16 *shortName = wcsrchr(methodNameBuf, _u('.'));
304+
charcount_t shortNameOffset = 0;
305+
if (shortName != nullptr)
317306
{
318-
// Only overwrite the name of the function object if it was anonymous coming in
319-
// If the input function was named, it is likely intentional
320-
existingName = nullptr;
307+
shortName++;
308+
shortNameOffset = static_cast<charcount_t>(shortName - methodNameBuf);
321309
}
322-
}
323310

324-
if (existingName == nullptr || JavascriptOperators::IsUndefined(existingName))
325-
{
326-
// It is convenient to set the name here rather than in script, since it is often duplicated.
327-
JavascriptString *funcName = displayName;
328-
if (shortName)
311+
scriptFunction->GetFunctionProxy()->EnsureDeserialized()->SetDisplayName(methodNameBuf, methodNameLength, shortNameOffset);
312+
313+
// handle the name property AFTER handling isConstructor, because this can initialize the function's deferred type
314+
Var existingName = nullptr;
315+
if (JavascriptOperators::GetOwnProperty(scriptFunction, PropertyIds::name, &existingName, scriptContext, nullptr))
329316
{
330-
funcName = JavascriptString::NewCopyBuffer(shortName, methodNameLength - shortNameOffset, scriptContext);
317+
JavascriptString *existingNameString = JavascriptString::FromVar(existingName);
318+
if (existingNameString->GetLength() == 0)
319+
{
320+
// Only overwrite the name of the function object if it was anonymous coming in
321+
// If the input function was named, it is likely intentional
322+
existingName = nullptr;
323+
}
331324
}
332325

333-
scriptFunction->SetPropertyWithAttributes(PropertyIds::name, funcName, PropertyConfigurable, nullptr);
326+
if (existingName == nullptr || JavascriptOperators::IsUndefined(existingName))
327+
{
328+
// It is convenient to set the name here rather than in script, since it is often duplicated.
329+
JavascriptString *funcName = displayName;
330+
if (shortName)
331+
{
332+
funcName = JavascriptString::NewCopyBuffer(shortName, methodNameLength - shortNameOffset, scriptContext);
333+
}
334+
335+
scriptFunction->SetPropertyWithAttributes(PropertyIds::name, funcName, PropertyConfigurable, nullptr);
336+
}
337+
338+
scriptFunction->GetFunctionProxy()->SetIsPublicLibraryCode();
334339
}
335340

336341
if (isJsBuiltIn)
@@ -342,15 +347,11 @@ namespace Js
342347
scriptFunction->SetEnvironment(const_cast<FrameDisplay *>(&StrictNullFrameDisplay));
343348

344349
// TODO(jahorto): investigate force-inlining Intl code
350+
scriptFunction->GetFunctionProxy()->EnsureDeserialized();
345351
AssertOrFailFast(scriptFunction->HasFunctionBody());
346352
scriptFunction->GetFunctionBody()->SetJsBuiltInForceInline();
347353
}
348354

349-
if (isPublic)
350-
{
351-
scriptFunction->GetFunctionProxy()->SetIsPublicLibraryCode();
352-
}
353-
354355
return scriptFunction;
355356
}
356357

lib/Runtime/Library/JsBuiltInEngineInterfaceExtensionObject.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,15 @@ namespace Js
259259
JavascriptLibrary * library = scriptContext->GetLibrary();
260260

261261
JavascriptString* methodName = JavascriptString::UnsafeFromVar(args.Values[1]);
262-
ScriptFunction* func = EngineInterfaceObject::CreateLibraryCodeScriptFunction(ScriptFunction::UnsafeFromVar(args.Values[2]), methodName, false /* isConstructor */, true /* isJsBuiltIn */, false /* isPublic */);
262+
263+
// chakra library functions, since they aren't public, can be constructors (__chakraLibrary.ArrayIterator is one)
264+
ScriptFunction* func = EngineInterfaceObject::CreateLibraryCodeScriptFunction(
265+
ScriptFunction::UnsafeFromVar(args.Values[2]),
266+
methodName,
267+
true /* isConstructor */,
268+
true /* isJsBuiltIn */,
269+
false /* isPublic */
270+
);
263271

264272
PropertyIds functionIdentifier = JavascriptOperators::GetPropertyId(methodName, scriptContext);
265273

0 commit comments

Comments
 (0)