JavascriptGeneratorFunction.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  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. FunctionInfo JavascriptGeneratorFunction::functionInfo(
  9. FORCE_NO_WRITE_BARRIER_TAG(JavascriptGeneratorFunction::EntryGeneratorFunctionImplementation),
  10. (FunctionInfo::Attributes)(FunctionInfo::DoNotProfile | FunctionInfo::ErrorOnNew));
  11. FunctionInfo JavascriptAsyncFunction::functionInfo(
  12. FORCE_NO_WRITE_BARRIER_TAG(JavascriptGeneratorFunction::EntryAsyncFunctionImplementation),
  13. (FunctionInfo::Attributes)(FunctionInfo::DoNotProfile | FunctionInfo::ErrorOnNew));
  14. JavascriptGeneratorFunction::JavascriptGeneratorFunction(DynamicType* type)
  15. : ScriptFunctionBase(type, &functionInfo),
  16. scriptFunction(nullptr)
  17. {
  18. // Constructor used during copy on write.
  19. DebugOnly(VerifyEntryPoint());
  20. }
  21. JavascriptGeneratorFunction::JavascriptGeneratorFunction(DynamicType* type, GeneratorVirtualScriptFunction* scriptFunction)
  22. : ScriptFunctionBase(type, &functionInfo),
  23. scriptFunction(scriptFunction)
  24. {
  25. DebugOnly(VerifyEntryPoint());
  26. }
  27. JavascriptGeneratorFunction::JavascriptGeneratorFunction(DynamicType* type, FunctionInfo* functionInfo, GeneratorVirtualScriptFunction* scriptFunction)
  28. : ScriptFunctionBase(type, functionInfo),
  29. scriptFunction(scriptFunction)
  30. {
  31. DebugOnly(VerifyEntryPoint());
  32. }
  33. JavascriptAsyncFunction::JavascriptAsyncFunction(DynamicType* type, GeneratorVirtualScriptFunction* scriptFunction)
  34. : JavascriptGeneratorFunction(type, &functionInfo, scriptFunction)
  35. {
  36. DebugOnly(VerifyEntryPoint());
  37. }
  38. JavascriptAsyncFunction* JavascriptAsyncFunction::New(ScriptContext* scriptContext, GeneratorVirtualScriptFunction* scriptFunction)
  39. {
  40. return scriptContext->GetLibrary()->CreateAsyncFunction(functionInfo.GetOriginalEntryPoint(), scriptFunction);
  41. }
  42. bool JavascriptGeneratorFunction::Is(Var var)
  43. {
  44. if (JavascriptFunction::Is(var))
  45. {
  46. JavascriptFunction* obj = JavascriptFunction::UnsafeFromVar(var);
  47. return VirtualTableInfo<JavascriptGeneratorFunction>::HasVirtualTable(obj)
  48. || VirtualTableInfo<CrossSiteObject<JavascriptGeneratorFunction>>::HasVirtualTable(obj);
  49. }
  50. return false;
  51. }
  52. JavascriptGeneratorFunction* JavascriptGeneratorFunction::FromVar(Var var)
  53. {
  54. AssertOrFailFast(JavascriptGeneratorFunction::Is(var) || JavascriptAsyncFunction::Is(var));
  55. return static_cast<JavascriptGeneratorFunction*>(var);
  56. }
  57. JavascriptGeneratorFunction* JavascriptGeneratorFunction::UnsafeFromVar(Var var)
  58. {
  59. Assert(JavascriptGeneratorFunction::Is(var) || JavascriptAsyncFunction::Is(var));
  60. return static_cast<JavascriptGeneratorFunction*>(var);
  61. }
  62. bool JavascriptAsyncFunction::Is(Var var)
  63. {
  64. if (JavascriptFunction::Is(var))
  65. {
  66. JavascriptFunction* obj = JavascriptFunction::UnsafeFromVar(var);
  67. return VirtualTableInfo<JavascriptAsyncFunction>::HasVirtualTable(obj)
  68. || VirtualTableInfo<CrossSiteObject<JavascriptAsyncFunction>>::HasVirtualTable(obj);
  69. }
  70. return false;
  71. }
  72. JavascriptAsyncFunction* JavascriptAsyncFunction::FromVar(Var var)
  73. {
  74. AssertOrFailFast(JavascriptAsyncFunction::Is(var));
  75. return static_cast<JavascriptAsyncFunction*>(var);
  76. }
  77. JavascriptAsyncFunction* JavascriptAsyncFunction::UnsafeFromVar(Var var)
  78. {
  79. Assert(JavascriptAsyncFunction::Is(var));
  80. return static_cast<JavascriptAsyncFunction*>(var);
  81. }
  82. JavascriptGeneratorFunction* JavascriptGeneratorFunction::OP_NewScGenFunc(FrameDisplay *environment, FunctionInfoPtrPtr infoRef)
  83. {
  84. FunctionProxy* functionProxy = (*infoRef)->GetFunctionProxy();
  85. ScriptContext* scriptContext = functionProxy->GetScriptContext();
  86. bool hasSuperReference = functionProxy->HasSuperReference();
  87. GeneratorVirtualScriptFunction* scriptFunction = scriptContext->GetLibrary()->CreateGeneratorVirtualScriptFunction(functionProxy);
  88. scriptFunction->SetEnvironment(environment);
  89. scriptFunction->SetHasSuperReference(hasSuperReference);
  90. JS_ETW(EventWriteJSCRIPT_RECYCLER_ALLOCATE_FUNCTION(scriptFunction, EtwTrace::GetFunctionId(functionProxy)));
  91. JavascriptGeneratorFunction* genFunc =
  92. functionProxy->IsAsync()
  93. ? JavascriptAsyncFunction::New(scriptContext, scriptFunction)
  94. : scriptContext->GetLibrary()->CreateGeneratorFunction(functionInfo.GetOriginalEntryPoint(), scriptFunction);
  95. scriptFunction->SetRealGeneratorFunction(genFunc);
  96. return genFunc;
  97. }
  98. Var JavascriptGeneratorFunction::EntryGeneratorFunctionImplementation(RecyclableObject* function, CallInfo callInfo, ...)
  99. {
  100. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  101. ARGUMENTS(stackArgs, callInfo);
  102. Assert(!(callInfo.Flags & CallFlags_New));
  103. ScriptContext* scriptContext = function->GetScriptContext();
  104. JavascriptGeneratorFunction* generatorFunction = JavascriptGeneratorFunction::FromVar(function);
  105. // InterpreterStackFrame takes a pointer to the args, so copy them to the recycler heap
  106. // and use that buffer for this InterpreterStackFrame.
  107. Field(Var)* argsHeapCopy = RecyclerNewArray(scriptContext->GetRecycler(), Field(Var), stackArgs.Info.Count);
  108. CopyArray(argsHeapCopy, stackArgs.Info.Count, stackArgs.Values, stackArgs.Info.Count);
  109. Arguments heapArgs(callInfo, unsafe_write_barrier_cast<Var*>(argsHeapCopy));
  110. DynamicObject* prototype = scriptContext->GetLibrary()->CreateGeneratorConstructorPrototypeObject();
  111. JavascriptGenerator* generator = scriptContext->GetLibrary()->CreateGenerator(heapArgs, generatorFunction->scriptFunction, prototype);
  112. // Set the prototype from constructor
  113. JavascriptOperators::OrdinaryCreateFromConstructor(function, generator, prototype, scriptContext);
  114. // Call a next on the generator to execute till the beginning of the body
  115. CALL_ENTRYPOINT(scriptContext->GetThreadContext(), generator->EntryNext, function, CallInfo(CallFlags_Value, 1), generator);
  116. return generator;
  117. }
  118. Var JavascriptGeneratorFunction::EntryAsyncFunctionImplementation(RecyclableObject* function, CallInfo callInfo, ...)
  119. {
  120. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  121. ARGUMENTS(stackArgs, callInfo);
  122. ScriptContext* scriptContext = function->GetScriptContext();
  123. JavascriptLibrary* library = scriptContext->GetLibrary();
  124. RecyclableObject* prototype = scriptContext->GetLibrary()->GetNull();
  125. // InterpreterStackFrame takes a pointer to the args, so copy them to the recycler heap
  126. // and use that buffer for this InterpreterStackFrame.
  127. Field(Var)* argsHeapCopy = RecyclerNewArray(scriptContext->GetRecycler(), Field(Var), stackArgs.Info.Count);
  128. CopyArray(argsHeapCopy, stackArgs.Info.Count, stackArgs.Values, stackArgs.Info.Count);
  129. Arguments heapArgs(callInfo, unsafe_write_barrier_cast<Var*>(argsHeapCopy));
  130. JavascriptExceptionObject* e = nullptr;
  131. JavascriptPromiseResolveOrRejectFunction* resolve;
  132. JavascriptPromiseResolveOrRejectFunction* reject;
  133. JavascriptPromiseAsyncSpawnExecutorFunction* executor =
  134. library->CreatePromiseAsyncSpawnExecutorFunction(
  135. JavascriptPromise::EntryJavascriptPromiseAsyncSpawnExecutorFunction,
  136. scriptContext->GetLibrary()->CreateGenerator(heapArgs, JavascriptAsyncFunction::FromVar(function)->GetGeneratorVirtualScriptFunction(), prototype),
  137. stackArgs[0]);
  138. JavascriptPromise* promise = library->CreatePromise();
  139. JavascriptPromise::InitializePromise(promise, &resolve, &reject, scriptContext);
  140. try
  141. {
  142. CALL_FUNCTION(scriptContext->GetThreadContext(), executor, CallInfo(CallFlags_Value, 3), library->GetUndefined(), resolve, reject);
  143. }
  144. catch (const JavascriptException& err)
  145. {
  146. e = err.GetAndClear();
  147. }
  148. if (e != nullptr)
  149. {
  150. JavascriptPromise::TryRejectWithExceptionObject(e, reject, scriptContext);
  151. }
  152. return promise;
  153. }
  154. Var JavascriptGeneratorFunction::NewInstance(RecyclableObject* function, CallInfo callInfo, ...)
  155. {
  156. // Get called when creating a new generator function through the constructor (e.g. gf.__proto__.constructor) and sets EntryGeneratorFunctionImplementation as the entrypoint
  157. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  158. ARGUMENTS(args, callInfo);
  159. return JavascriptFunction::NewInstanceHelper(function->GetScriptContext(), function, callInfo, args, FunctionKind::Generator);
  160. }
  161. Var JavascriptGeneratorFunction::NewInstanceRestrictedMode(RecyclableObject* function, CallInfo callInfo, ...)
  162. {
  163. ScriptContext* scriptContext = function->GetScriptContext();
  164. scriptContext->CheckEvalRestriction();
  165. PROBE_STACK(scriptContext, Js::Constants::MinStackDefault);
  166. ARGUMENTS(args, callInfo);
  167. return JavascriptFunction::NewInstanceHelper(scriptContext, function, callInfo, args, FunctionKind::Generator);
  168. }
  169. JavascriptString* JavascriptGeneratorFunction::GetDisplayNameImpl() const
  170. {
  171. return scriptFunction->GetDisplayNameImpl();
  172. }
  173. Var JavascriptGeneratorFunction::GetHomeObj() const
  174. {
  175. return scriptFunction->GetHomeObj();
  176. }
  177. void JavascriptGeneratorFunction::SetHomeObj(Var homeObj)
  178. {
  179. scriptFunction->SetHomeObj(homeObj);
  180. }
  181. void JavascriptGeneratorFunction::SetComputedNameVar(Var computedNameVar)
  182. {
  183. scriptFunction->SetComputedNameVar(computedNameVar);
  184. }
  185. Var JavascriptGeneratorFunction::GetComputedNameVar() const
  186. {
  187. return scriptFunction->GetComputedNameVar();
  188. }
  189. bool JavascriptGeneratorFunction::IsAnonymousFunction() const
  190. {
  191. return scriptFunction->IsAnonymousFunction();
  192. }
  193. Var JavascriptGeneratorFunction::GetSourceString() const
  194. {
  195. return scriptFunction->GetSourceString();
  196. }
  197. Var JavascriptGeneratorFunction::EnsureSourceString()
  198. {
  199. return scriptFunction->EnsureSourceString();
  200. }
  201. PropertyQueryFlags JavascriptGeneratorFunction::HasPropertyQuery(PropertyId propertyId)
  202. {
  203. if (propertyId == PropertyIds::length)
  204. {
  205. return PropertyQueryFlags::Property_Found;
  206. }
  207. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  208. {
  209. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  210. return DynamicObject::HasPropertyQuery(propertyId);
  211. }
  212. return JavascriptFunction::HasPropertyQuery(propertyId);
  213. }
  214. PropertyQueryFlags JavascriptGeneratorFunction::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
  215. {
  216. BOOL result;
  217. if (GetPropertyBuiltIns(originalInstance, propertyId, value, info, requestContext, &result))
  218. {
  219. return JavascriptConversion::BooleanToPropertyQueryFlags(result);
  220. }
  221. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  222. {
  223. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  224. return DynamicObject::GetPropertyQuery(originalInstance, propertyId, value, info, requestContext);
  225. }
  226. return JavascriptFunction::GetPropertyQuery(originalInstance, propertyId, value, info, requestContext);
  227. }
  228. PropertyQueryFlags JavascriptGeneratorFunction::GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
  229. {
  230. PropertyRecord const* propertyRecord;
  231. this->GetScriptContext()->FindPropertyRecord(propertyNameString, &propertyRecord);
  232. if (propertyRecord != nullptr)
  233. {
  234. BOOL result;
  235. if (GetPropertyBuiltIns(originalInstance, propertyRecord->GetPropertyId(), value, info, requestContext, &result))
  236. {
  237. return JavascriptConversion::BooleanToPropertyQueryFlags(result);
  238. }
  239. if (propertyRecord->GetPropertyId() == PropertyIds::caller || propertyRecord->GetPropertyId() == PropertyIds::arguments)
  240. {
  241. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  242. return DynamicObject::GetPropertyQuery(originalInstance, propertyNameString, value, info, requestContext);
  243. }
  244. }
  245. return JavascriptFunction::GetPropertyQuery(originalInstance, propertyNameString, value, info, requestContext);
  246. }
  247. bool JavascriptGeneratorFunction::GetPropertyBuiltIns(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext, BOOL* result)
  248. {
  249. if (propertyId == PropertyIds::length)
  250. {
  251. // Cannot just call the base GetProperty for `length` because we need
  252. // to get the length from our private ScriptFunction instead of ourself.
  253. int len = 0;
  254. Var varLength;
  255. if (scriptFunction->GetProperty(this, PropertyIds::length, &varLength, NULL, requestContext))
  256. {
  257. len = JavascriptConversion::ToInt32(varLength, requestContext);
  258. }
  259. *value = JavascriptNumber::ToVar(len, requestContext);
  260. *result = true;
  261. return true;
  262. }
  263. return false;
  264. }
  265. PropertyQueryFlags JavascriptGeneratorFunction::GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
  266. {
  267. return JavascriptGeneratorFunction::GetPropertyQuery(originalInstance, propertyId, value, info, requestContext);
  268. }
  269. BOOL JavascriptGeneratorFunction::SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
  270. {
  271. BOOL result;
  272. if (SetPropertyBuiltIns(propertyId, value, flags, info, &result))
  273. {
  274. return result;
  275. }
  276. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  277. {
  278. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  279. return DynamicObject::SetProperty(propertyId, value, flags, info);
  280. }
  281. return JavascriptFunction::SetProperty(propertyId, value, flags, info);
  282. }
  283. BOOL JavascriptGeneratorFunction::SetProperty(JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
  284. {
  285. PropertyRecord const* propertyRecord;
  286. this->GetScriptContext()->FindPropertyRecord(propertyNameString, &propertyRecord);
  287. if (propertyRecord != nullptr)
  288. {
  289. BOOL result;
  290. if (SetPropertyBuiltIns(propertyRecord->GetPropertyId(), value, flags, info, &result))
  291. {
  292. return result;
  293. }
  294. if (propertyRecord->GetPropertyId() == PropertyIds::caller || propertyRecord->GetPropertyId() == PropertyIds::arguments)
  295. {
  296. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  297. return DynamicObject::SetProperty(propertyNameString, value, flags, info);
  298. }
  299. }
  300. return JavascriptFunction::SetProperty(propertyNameString, value, flags, info);
  301. }
  302. bool JavascriptGeneratorFunction::SetPropertyBuiltIns(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info, BOOL* result)
  303. {
  304. if (propertyId == PropertyIds::length)
  305. {
  306. JavascriptError::ThrowCantAssignIfStrictMode(flags, this->GetScriptContext());
  307. *result = false;
  308. return true;
  309. }
  310. return false;
  311. }
  312. BOOL JavascriptGeneratorFunction::SetAccessors(PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags)
  313. {
  314. if (propertyId == PropertyIds::length)
  315. {
  316. return this->scriptFunction->SetAccessors(propertyId, getter, setter, flags);
  317. }
  318. return JavascriptFunction::SetAccessors(propertyId, getter, setter, flags);
  319. }
  320. BOOL JavascriptGeneratorFunction::GetAccessors(PropertyId propertyId, Var *getter, Var *setter, ScriptContext * requestContext)
  321. {
  322. if (propertyId == PropertyIds::length)
  323. {
  324. return this->scriptFunction->GetAccessors(propertyId, getter, setter, requestContext);
  325. }
  326. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  327. {
  328. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  329. return DynamicObject::GetAccessors(propertyId, getter, setter, requestContext);
  330. }
  331. return JavascriptFunction::GetAccessors(propertyId, getter, setter, requestContext);
  332. }
  333. DescriptorFlags JavascriptGeneratorFunction::GetSetter(PropertyId propertyId, Var *setterValue, PropertyValueInfo* info, ScriptContext* requestContext)
  334. {
  335. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  336. {
  337. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  338. return DynamicObject::GetSetter(propertyId, setterValue, info, requestContext);
  339. }
  340. if (propertyId == PropertyIds::length)
  341. {
  342. return this->scriptFunction->GetSetter(propertyId, setterValue, info, requestContext);
  343. }
  344. return JavascriptFunction::GetSetter(propertyId, setterValue, info, requestContext);
  345. }
  346. DescriptorFlags JavascriptGeneratorFunction::GetSetter(JavascriptString* propertyNameString, Var *setterValue, PropertyValueInfo* info, ScriptContext* requestContext)
  347. {
  348. PropertyRecord const* propertyRecord;
  349. this->GetScriptContext()->FindPropertyRecord(propertyNameString, &propertyRecord);
  350. if (propertyRecord != nullptr)
  351. {
  352. if (propertyRecord->GetPropertyId() == PropertyIds::length)
  353. {
  354. return this->scriptFunction->GetSetter(propertyNameString, setterValue, info, requestContext);
  355. }
  356. if ((propertyRecord->GetPropertyId() == PropertyIds::caller || propertyRecord->GetPropertyId() == PropertyIds::arguments))
  357. {
  358. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  359. return DynamicObject::GetSetter(propertyNameString, setterValue, info, requestContext);
  360. }
  361. }
  362. return JavascriptFunction::GetSetter(propertyNameString, setterValue, info, requestContext);
  363. }
  364. BOOL JavascriptGeneratorFunction::InitProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
  365. {
  366. return SetProperty(propertyId, value, PropertyOperation_None, info);
  367. }
  368. BOOL JavascriptGeneratorFunction::DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags)
  369. {
  370. if (propertyId == PropertyIds::length)
  371. {
  372. return false;
  373. }
  374. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  375. {
  376. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  377. return DynamicObject::DeleteProperty(propertyId, flags);
  378. }
  379. return JavascriptFunction::DeleteProperty(propertyId, flags);
  380. }
  381. BOOL JavascriptGeneratorFunction::DeleteProperty(JavascriptString *propertyNameString, PropertyOperationFlags flags)
  382. {
  383. JsUtil::CharacterBuffer<WCHAR> propertyName(propertyNameString->GetString(), propertyNameString->GetLength());
  384. if (BuiltInPropertyRecords::length.Equals(propertyName))
  385. {
  386. return false;
  387. }
  388. if (BuiltInPropertyRecords::caller.Equals(propertyName) || BuiltInPropertyRecords::arguments.Equals(propertyName))
  389. {
  390. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  391. return DynamicObject::DeleteProperty(propertyNameString, flags);
  392. }
  393. return JavascriptFunction::DeleteProperty(propertyNameString, flags);
  394. }
  395. BOOL JavascriptGeneratorFunction::IsWritable(PropertyId propertyId)
  396. {
  397. if (propertyId == PropertyIds::length)
  398. {
  399. return false;
  400. }
  401. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  402. {
  403. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  404. return DynamicObject::IsWritable(propertyId);
  405. }
  406. return JavascriptFunction::IsWritable(propertyId);
  407. }
  408. BOOL JavascriptGeneratorFunction::IsEnumerable(PropertyId propertyId)
  409. {
  410. if (propertyId == PropertyIds::length)
  411. {
  412. return false;
  413. }
  414. if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
  415. {
  416. // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
  417. return DynamicObject::IsEnumerable(propertyId);
  418. }
  419. return JavascriptFunction::IsEnumerable(propertyId);
  420. }
  421. #if ENABLE_TTD
  422. TTD::NSSnapObjects::SnapObjectType JavascriptGeneratorFunction::GetSnapTag_TTD() const
  423. {
  424. //we override this with invalid to make sure it isn't unexpectedly handled by the parent class
  425. return TTD::NSSnapObjects::SnapObjectType::Invalid;
  426. }
  427. void JavascriptGeneratorFunction::ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc)
  428. {
  429. TTDAssert(false, "Invalid -- JavascriptGeneratorFunction");
  430. }
  431. TTD::NSSnapObjects::SnapObjectType JavascriptAsyncFunction::GetSnapTag_TTD() const
  432. {
  433. //we override this with invalid to make sure it isn't unexpectedly handled by the parent class
  434. return TTD::NSSnapObjects::SnapObjectType::Invalid;
  435. }
  436. void JavascriptAsyncFunction::ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc)
  437. {
  438. TTDAssert(false, "Invalid -- JavascriptAsyncFunction");
  439. }
  440. TTD::NSSnapObjects::SnapObjectType GeneratorVirtualScriptFunction::GetSnapTag_TTD() const
  441. {
  442. //we override this with invalid to make sure it isn't unexpectedly handled by the parent class
  443. return TTD::NSSnapObjects::SnapObjectType::Invalid;
  444. }
  445. void GeneratorVirtualScriptFunction::ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc)
  446. {
  447. TTDAssert(false, "Invalid -- GeneratorVirtualScriptFunction");
  448. }
  449. #endif
  450. }