RuntimeFunction.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. namespace Js
  7. {
  8. RuntimeFunction::RuntimeFunction(DynamicType * type)
  9. : JavascriptFunction(type), isDisplayString(false), functionNameId(nullptr)
  10. {}
  11. RuntimeFunction::RuntimeFunction(DynamicType * type, FunctionInfo * functionInfo)
  12. : JavascriptFunction(type, functionInfo), isDisplayString(false), functionNameId(nullptr)
  13. {}
  14. RuntimeFunction::RuntimeFunction(DynamicType * type, FunctionInfo * functionInfo, ConstructorCache* cache)
  15. : JavascriptFunction(type, functionInfo, cache), isDisplayString(false), functionNameId(nullptr)
  16. {}
  17. JavascriptString *
  18. RuntimeFunction::EnsureSourceString()
  19. {
  20. JavascriptLibrary* library = this->GetLibrary();
  21. ScriptContext * scriptContext = library->GetScriptContext();
  22. JavascriptString * retStr = nullptr;
  23. if (this->isDisplayString)
  24. {
  25. return VarTo<JavascriptString>(this->functionNameId);
  26. }
  27. if (this->functionNameId == nullptr)
  28. {
  29. retStr = library->GetFunctionDisplayString();
  30. }
  31. else
  32. {
  33. if (this->GetTypeHandler()->IsDeferredTypeHandler())
  34. {
  35. JavascriptString* functionName = nullptr;
  36. DebugOnly(bool status = ) this->GetFunctionName(&functionName);
  37. Assert(status);
  38. this->SetPropertyWithAttributes(PropertyIds::name, functionName, PropertyConfigurable, nullptr);
  39. }
  40. if (TaggedInt::Is(this->functionNameId))
  41. {
  42. // This has a side-effect where any other code (such as debugger) that uses functionNameId value will now get the value like "function foo() { native code }"
  43. // instead of just "foo". Alternative ways will need to be devised; if it's not desirable to use this full display name value in those cases.
  44. retStr = GetNativeFunctionDisplayString(scriptContext, scriptContext->GetPropertyString(TaggedInt::ToInt32(this->functionNameId)));
  45. }
  46. else
  47. {
  48. retStr = GetNativeFunctionDisplayString(scriptContext, VarTo<JavascriptString>(this->functionNameId));
  49. }
  50. }
  51. this->functionNameId = retStr;
  52. this->isDisplayString = true;
  53. return retStr;
  54. }
  55. void
  56. RuntimeFunction::SetFunctionNameId(Var nameId)
  57. {
  58. Assert(functionNameId == NULL);
  59. Assert(TaggedInt::Is(nameId) || Js::VarIs<Js::JavascriptString>(nameId));
  60. // We are only reference the propertyId, it needs to be tracked to stay alive
  61. Assert(!TaggedInt::Is(nameId) || this->GetScriptContext()->IsTrackedPropertyId(TaggedInt::ToInt32(nameId)));
  62. this->isDisplayString = false;
  63. this->functionNameId = nameId;
  64. }
  65. #if ENABLE_TTD
  66. void RuntimeFunction::MarkVisitKindSpecificPtrs(TTD::SnapshotExtractor* extractor)
  67. {
  68. if(this->functionNameId != nullptr)
  69. {
  70. extractor->MarkVisitVar(this->functionNameId);
  71. }
  72. Var revokableProxy = nullptr;
  73. RuntimeFunction* function = const_cast<RuntimeFunction*>(this);
  74. if(function->GetInternalProperty(function, Js::InternalPropertyIds::RevocableProxy, &revokableProxy, nullptr, this->GetScriptContext()))
  75. {
  76. extractor->MarkVisitVar(revokableProxy);
  77. }
  78. }
  79. TTD::NSSnapObjects::SnapObjectType RuntimeFunction::GetSnapTag_TTD() const
  80. {
  81. Var revokableProxy = nullptr;
  82. RuntimeFunction* function = const_cast<RuntimeFunction*>(this);
  83. if(function->GetInternalProperty(function, Js::InternalPropertyIds::RevocableProxy, &revokableProxy, nullptr, this->GetScriptContext()))
  84. {
  85. return TTD::NSSnapObjects::SnapObjectType::SnapRuntimeRevokerFunctionObject;
  86. }
  87. else
  88. {
  89. return TTD::NSSnapObjects::SnapObjectType::SnapRuntimeFunctionObject;
  90. }
  91. }
  92. void RuntimeFunction::ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc)
  93. {
  94. //
  95. //TODO: need to add more promise support
  96. //
  97. Var revokableProxy = nullptr;
  98. RuntimeFunction* function = const_cast<RuntimeFunction*>(this);
  99. if(function->GetInternalProperty(function, Js::InternalPropertyIds::RevocableProxy, &revokableProxy, nullptr, this->GetScriptContext()))
  100. {
  101. TTD_PTR_ID* proxyId = alloc.SlabAllocateStruct<TTD_PTR_ID>();
  102. *proxyId = (JavascriptOperators::GetTypeId(revokableProxy) != TypeIds_Null) ? TTD_CONVERT_VAR_TO_PTR_ID(revokableProxy) : TTD_INVALID_PTR_ID;
  103. if(*proxyId == TTD_INVALID_PTR_ID)
  104. {
  105. TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<TTD_PTR_ID*, TTD::NSSnapObjects::SnapObjectType::SnapRuntimeRevokerFunctionObject>(objData, proxyId);
  106. }
  107. else
  108. {
  109. TTDAssert(TTD::JsSupport::IsVarComplexKind(revokableProxy), "Huh, it looks like we need to check before adding this as a dep on.");
  110. uint32 depOnCount = 1;
  111. TTD_PTR_ID* depOnArray = alloc.SlabAllocateArray<TTD_PTR_ID>(1);
  112. depOnArray[0] = TTD_CONVERT_VAR_TO_PTR_ID(revokableProxy);
  113. TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<TTD_PTR_ID*, TTD::NSSnapObjects::SnapObjectType::SnapRuntimeRevokerFunctionObject>(objData, proxyId, alloc, depOnCount, depOnArray);
  114. }
  115. }
  116. else
  117. {
  118. TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<void*, TTD::NSSnapObjects::SnapObjectType::SnapRuntimeFunctionObject>(objData, nullptr);
  119. }
  120. }
  121. #endif
  122. };