Var JavascriptExternalFunction::HandleRecordReplayExternalFunction_Thunk(Js::JavascriptFunction* function, CallInfo& callInfo, Arguments& args, ScriptContext* scriptContext) { JavascriptExternalFunction* externalFunction = static_cast<JavascriptExternalFunction*>(function); Var result = nullptr; if(scriptContext->ShouldPerformReplayAction()) { TTD::TTDNestingDepthAutoAdjuster logPopper(scriptContext->GetThreadContext()); scriptContext->GetThreadContext()->TTDLog->ReplayExternalCallEvent(externalFunction, args, &result); } else { TTDAssert(scriptContext->ShouldPerformRecordAction(), "Check either record/replay before calling!!!"); TTD::EventLog* elog = scriptContext->GetThreadContext()->TTDLog; TTD::TTDNestingDepthAutoAdjuster logPopper(scriptContext->GetThreadContext()); TTD::NSLogEvents::EventLogEntry* callEvent = elog->RecordExternalCallEvent(externalFunction, scriptContext->GetThreadContext()->TTDRootNestingCount, args, false); BEGIN_LEAVE_SCRIPT_WITH_EXCEPTION(scriptContext) { // Don't do stack probe since BEGIN_LEAVE_SCRIPT_WITH_EXCEPTION does that for us already result = externalFunction->nativeMethod(function, callInfo, args.Values); } END_LEAVE_SCRIPT_WITH_EXCEPTION(scriptContext); //Exceptions should be prohibited so no need to do extra work elog->RecordExternalCallEvent_Complete(externalFunction, callEvent, result); } return result; }
Var JavascriptExternalFunction::HandleRecordReplayExternalFunction_StdThunk(Js::RecyclableObject* function, CallInfo& callInfo, Arguments& args, ScriptContext* scriptContext) { JavascriptExternalFunction* externalFunction = static_cast<JavascriptExternalFunction*>(function); Var result = nullptr; if(scriptContext->ShouldPerformReplayAction()) { TTD::TTDNestingDepthAutoAdjuster logPopper(scriptContext->GetThreadContext()); scriptContext->GetThreadContext()->TTDLog->ReplayExternalCallEvent(externalFunction, args.Info.Count, args.Values, &result); } else { AssertMsg(scriptContext->ShouldPerformRecordAction(), "Check either record/replay before calling!!!"); TTD::EventLog* elog = scriptContext->GetThreadContext()->TTDLog; TTD::TTDNestingDepthAutoAdjuster logPopper(scriptContext->GetThreadContext()); TTD::NSLogEvents::EventLogEntry* callEvent = elog->RecordExternalCallEvent(externalFunction, scriptContext->GetThreadContext()->TTDRootNestingCount, args.Info.Count, args.Values, true); BEGIN_LEAVE_SCRIPT(scriptContext) { result = externalFunction->stdCallNativeMethod(function, ((callInfo.Flags & CallFlags_New) != 0), args.Values, args.Info.Count, externalFunction->callbackState); } END_LEAVE_SCRIPT(scriptContext); elog->RecordExternalCallEvent_Complete(externalFunction, callEvent, result); } return result; }
Var JavascriptExternalFunction::HandleRecordReplayExternalFunction_StdThunk(Js::RecyclableObject* function, CallInfo& callInfo, Arguments& args, ScriptContext* scriptContext) { JavascriptExternalFunction* externalFunction = static_cast<JavascriptExternalFunction*>(function); Var result = nullptr; if(scriptContext->ShouldPerformReplayAction()) { TTD::TTDNestingDepthAutoAdjuster logPopper(scriptContext->GetThreadContext()); scriptContext->GetThreadContext()->TTDLog->ReplayExternalCallEvent(externalFunction, args, &result); } else { if (args.Info.Count > USHORT_MAX) { // Due to compat reasons, stdcall external functions expect a ushort count of args. // To support more than this we will need a new API. Js::JavascriptError::ThrowTypeError(scriptContext, JSERR_ArgListTooLarge); } TTDAssert(scriptContext->ShouldPerformRecordAction(), "Check either record/replay before calling!!!"); TTD::EventLog* elog = scriptContext->GetThreadContext()->TTDLog; TTD::TTDNestingDepthAutoAdjuster logPopper(scriptContext->GetThreadContext()); TTD::NSLogEvents::EventLogEntry* callEvent = elog->RecordExternalCallEvent(externalFunction, scriptContext->GetThreadContext()->TTDRootNestingCount, args, true); StdCallJavascriptMethodInfo info = { args[0], args.HasNewTarget() ? args.GetNewTarget() : args.IsNewCall() ? function : scriptContext->GetLibrary()->GetUndefined(), args.IsNewCall() }; BEGIN_LEAVE_SCRIPT(scriptContext) { result = externalFunction->stdCallNativeMethod(function, args.Values, static_cast<ushort>(args.Info.Count), &info, externalFunction->callbackState); } END_LEAVE_SCRIPT(scriptContext); elog->RecordExternalCallEvent_Complete(externalFunction, callEvent, result); } return result; }