{"action":"created","comment":{"url":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/comments/185074571","pull_request_review_id":116394104,"id":185074571,"diff_hunk":"@@ -0,0 +1,467 @@\n+//-------------------------------------------------------------------------------------------------------\n+// Copyright (C) Microsoft. All rights reserved.\n+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.\n+//-------------------------------------------------------------------------------------------------------\n+\n+#include \"ParserPch.h\"\n+\n+#include \"Memory/AutoPtr.h\"\n+#include \"Common/Event.h\"\n+#include \"Base/ThreadContextTlsEntry.h\"\n+#include \"base/ThreadBoundThreadContextManager.h\"\n+#include \"Base/Utf8SourceInfo.h\"\n+#include \"BGParseManager.h\"\n+#include \"Base/ScriptContext.h\"\n+#include \"ByteCodeSerializer.h\"\n+\n+// Global, process singleton\n+BGParseManager* BGParseManager::s_BGParseManager = nullptr;\n+DWORD           BGParseManager::s_lastCookie = 0;\n+CriticalSection BGParseManager::s_staticMemberLock;\n+\n+// Static member management\n+BGParseManager* BGParseManager::GetBGParseManager()\n+{\n+    AutoCriticalSection lock(&s_staticMemberLock);\n+    if (s_BGParseManager == nullptr)\n+    {        \n+        AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_DisableCheck);\n+        s_BGParseManager = HeapNew(BGParseManager);\n+        s_BGParseManager->Processor()->AddManager(s_BGParseManager);\n+    }\n+    return s_BGParseManager;\n+}\n+\n+void BGParseManager::DeleteBGParseManager()\n+{\n+    AutoCriticalSection lock(&s_staticMemberLock);\n+    if (s_BGParseManager != nullptr)\n+    {\n+        BGParseManager* manager = s_BGParseManager;\n+        s_BGParseManager = nullptr;\n+        HeapDelete(manager);\n+    }\n+}\n+\n+DWORD BGParseManager::GetNextCookie()\n+{\n+    AutoCriticalSection lock(&s_staticMemberLock);\n+    return ++s_lastCookie;\n+}\n+\n+\n+// Note: runs on any thread\n+BGParseManager::BGParseManager()\n+    : JsUtil::WaitableJobManager(ThreadBoundThreadContextManager::GetSharedJobProcessor())\n+{\n+}\n+\n+// Note: runs on any thread\n+BGParseManager::~BGParseManager()\n+{\n+    // First, remove the manager from the JobProcessor so that any remaining jobs\n+    // are moved back into this manager's processed workitem list\n+    if (Processor()->HasManager(this))\n+    {\n+        Processor()->RemoveManager(this);\n+    }\n+\n+    Assert(this->workitemsProcessing.IsEmpty());\n+\n+    // Now, free all remaining processed jobs\n+    BGParseWorkItem *item = (BGParseWorkItem*)this->workitemsProcessed.Head();\n+    while (item != nullptr)\n+    {\n+        // Get the next item first so that the current item\n+        // can be safely removed and freed\n+        BGParseWorkItem* temp = item;\n+        item = (BGParseWorkItem*)item->Next();\n+\n+        this->workitemsProcessed.Unlink(temp);\n+        HeapDelete(temp);\n+    }\n+}\n+\n+// Returns the BGParseWorkItem that matches the provided cookie\n+// Note: runs on any thread\n+BGParseWorkItem* BGParseManager::FindJob(DWORD dwCookie, bool waitForResults)\n+{\n+    AutoOptionalCriticalSection autoLock(Processor()->GetCriticalSection());\n+\n+    Assert(dwCookie != 0);\n+    BGParseWorkItem* matchedWorkitem = nullptr;\n+\n+    // First, look among processed jobs\n+    for (BGParseWorkItem *item = (BGParseWorkItem*)this->workitemsProcessed.Head(); item != nullptr && matchedWorkitem == nullptr; item = (BGParseWorkItem*)item->Next())\n+    {\n+        if (item->GetCookie() == dwCookie)\n+        {\n+            matchedWorkitem = item;\n+        }\n+    }\n+\n+    if (matchedWorkitem == nullptr)\n+    {\n+        // Then, look among processing jobs\n+        for (BGParseWorkItem *item = (BGParseWorkItem*)this->workitemsProcessing.Head(); item != nullptr && matchedWorkitem == nullptr; item = (BGParseWorkItem*)item->Next())\n+        {\n+            if (item->GetCookie() == dwCookie)\n+            {\n+                matchedWorkitem = item;\n+            }\n+        }\n+\n+        // Lastly, look among active jobs\n+        if (matchedWorkitem == nullptr)\n+        {\n+            Processor()->ForEachJob([&](JsUtil::Job * job) {\n+                if (job->Manager() == this)\n+                {\n+                    BGParseWorkItem* workitem = (BGParseWorkItem*)job;\n+                    if (workitem->GetCookie() == dwCookie)\n+                    {\n+                        matchedWorkitem = workitem;\n+                        return false;\n+                    }\n+                }\n+                return true;\n+            });\n+        }\n+\n+        // Since this job isn't already processed and the caller needs the results, create an event\n+        // that the caller can wait on for results to complete\n+        if (waitForResults && matchedWorkitem != nullptr)\n+        {\n+            // TODO: Is it possible for one event to be shared to reduce the number of heap allocations?\n+            matchedWorkitem->CreateCompletionEvent();\n+        }\n+    }\n+\n+    return matchedWorkitem;\n+}\n+\n+// Creates a new job to parse the provided script on a background thread\n+// Note: runs on any thread\n+HRESULT BGParseManager::QueueBackgroundParse(LPCUTF8 pszSrc, size_t cbLength, char16 *fullPath, DWORD* dwBgParseCookie)\n+{\n+    HRESULT hr = S_OK;\n+    if (cbLength > 0)\n+    {\n+        BGParseWorkItem* workitem;\n+        {\n+            AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_DisableCheck);\n+            workitem = HeapNew(BGParseWorkItem, this, (const byte *)pszSrc, cbLength, fullPath);\n+        }\n+\n+        // Add the job to the processor\n+        {\n+            AutoOptionalCriticalSection autoLock(Processor()->GetCriticalSection());\n+            Processor()->AddJob(workitem, false /*prioritize*/);\n+        }\n+\n+        (*dwBgParseCookie) = workitem->GetCookie();\n+\n+        if (PHASE_TRACE1(Js::BgParsePhase))\n+        {\n+            Js::Tick now = Js::Tick::Now();\n+            Output::Print(\n+                _u(\"[BgParse: Start -- cookie: %04d on thread 0x%X at %.2f ms -- %s]\\n\"),\n+                workitem->GetCookie(),\n+                ::GetCurrentThreadId(),\n+                now.ToMilliseconds(),\n+                fullPath\n+            );\n+        }\n+    }\n+    else\n+    {\n+        hr = E_INVALIDARG;\n+    }\n+\n+    return hr;\n+}\n+\n+// Returns the data provided when the parse was queued\n+// Note: runs on any thread, but the buffer lifetimes are not guaranteed after parse results are returned\n+HRESULT BGParseManager::GetInputFromCookie(DWORD cookie, LPCUTF8* ppszSrc, size_t* pcbLength)\n+{\n+    HRESULT hr = E_FAIL;\n+\n+    // Find the job associated with this cookie\n+    BGParseWorkItem* workitem = FindJob(cookie, false);\n+    if (workitem != nullptr)\n+    {\n+        (*ppszSrc) = workitem->GetScriptSrc();\n+        (*pcbLength) = workitem->GetScriptLength();\n+        hr = S_OK;\n+    }\n+\n+    return hr;\n+}\n+\n+// Deserializes the background parse results into this thread\n+// Note: *must* run on a UI/Execution thread with an available ScriptContext\n+HRESULT BGParseManager::GetParseResults(Js::ScriptContext* scriptContextUI, DWORD cookie, LPCUTF8 pszSrc, SRCINFO const * pSrcInfo, Js::ParseableFunctionInfo** ppFunc, CompileScriptException* pse, size_t& srcLength)\n+{\n+    // TODO: Is there a way to cache the environment from which serialization begins to\n+    // determine whether or not deserialization will succeed? Specifically, being able\n+    // to assert/compare the flags used during background parse with the flags expected\n+    // from the UI thread?\n+\n+    HRESULT hr = E_FAIL;\n+\n+    // Find the job associated with this cookie\n+    BGParseWorkItem* workitem = FindJob(cookie, true);\n+    if (workitem != nullptr)\n+    {\n+        // Synchronously wait for the job to complete\n+        workitem->WaitForCompletion();\n+\n+        Field(Js::FunctionBody*) functionBody = nullptr;\n+        hr = workitem->GetParseHR();\n+        if (hr == S_OK)\n+        {\n+            srcLength = workitem->GetParseSourceLength();\n+            hr = Js::ByteCodeSerializer::DeserializeFromBuffer(\n+                scriptContextUI,\n+                0, // flags\n+                (const byte *)pszSrc,\n+                pSrcInfo,\n+                workitem->GetReturnBuffer(),\n+                nullptr, // nativeModule\n+                &functionBody\n+            );\n+        }\n+\n+        *ppFunc = functionBody;\n+        workitem->TransferCSE(pse);\n+    }\n+\n+    if (PHASE_TRACE1(Js::BgParsePhase))\n+    {\n+        Js::Tick now = Js::Tick::Now();\n+        Output::Print(\n+            _u(\"[BgParse: End   -- cookie: %04d on thread 0x%X at %.2f ms -- hr: 0x%X]\\n\"),\n+            workitem->GetCookie(),\n+            ::GetCurrentThreadId(),\n+            now.ToMilliseconds(),\n+            hr\n+        );\n+    }\n+\n+    return hr;\n+}\n+\n+// Overloaded function called by JobProcessor to do work\n+// Note: runs on background thread\n+bool BGParseManager::Process(JsUtil::Job *const job, JsUtil::ParallelThreadData *threadData) \n+{\n+    Assert(job->Manager() == this);\n+\n+    // Create script context on this thread\n+    ThreadContext* threadContext = ThreadBoundThreadContextManager::EnsureContextForCurrentThread();\n+\n+    // If there is no script context created for this thread yet, create it now\n+    if (threadData->scriptContextBG == nullptr)\n+    {\n+        threadData->scriptContextBG = Js::ScriptContext::New(threadContext);\n+        threadData->scriptContextBG->Initialize();\n+        threadData->canDecommit = true;\n+    }\n+    \n+    // Parse the workitem's data\n+    BGParseWorkItem* workItem = (BGParseWorkItem*)job;\n+    workItem->ParseUTF8Core(threadData->scriptContextBG);\n+\n+    return true;\n+}\n+\n+// Callback before the provided job will be processed\n+// Note: runs on any thread\n+void BGParseManager::JobProcessing(JsUtil::Job* job)\n+{\n+    Assert(job->Manager() == this);\n+    Assert(Processor()->GetCriticalSection()->IsLocked());\n+\n+    this->workitemsProcessing.LinkToEnd((BGParseWorkItem*)job);\n+}\n+\n+// Callback after the provided job was processed. succeeded is true if the job\n+// was executed as well.\n+// Note: runs on any thread\n+void BGParseManager::JobProcessed(JsUtil::Job *const job, const bool succeeded)\n+{\n+    Assert(job->Manager() == this);\n+    Assert(Processor()->GetCriticalSection()->IsLocked());\n+\n+    BGParseWorkItem* workItem = (BGParseWorkItem*)job;\n+    if (succeeded)\n+    {\n+        Assert(this->workitemsProcessing.Contains(job));\n+        this->workitemsProcessing.Unlink(job);\n+    }\n+\n+    this->workitemsProcessed.LinkToEnd(job);\n+    workItem->JobProcessed();\n+}\n+\n+// Define needed for jobs.inl\n+// Note: Runs on any thread\n+BGParseWorkItem* BGParseManager::GetJob(BGParseWorkItem* workitem)\n+{\n+    Assert(!\"BGParseManager::WasAddedToJobProcessor\");\n+    return nullptr;\n+}\n+\n+// Define needed for jobs.inl\n+// Note: Runs on any thread\n+bool BGParseManager::WasAddedToJobProcessor(JsUtil::Job *const job) const\n+{\n+    Assert(!\"BGParseManager::WasAddedToJobProcessor\");\n+    return true;\n+}\n+\n+\n+// Note: runs on any thread\n+BGParseWorkItem::BGParseWorkItem(\n+    BGParseManager* manager,\n+    const byte* pszScript,\n+    size_t cbScript,\n+    char16 *fullPath\n+    )\n+    : JsUtil::Job(manager),\n+    script(pszScript),\n+    cb(cbScript),\n+    path(nullptr),\n+    parseHR(S_OK),\n+    parseSourceLength(0),\n+    bufferReturn(nullptr),\n+    bufferReturnBytes(0),\n+    complete(nullptr)\n+{\n+    this->cookie = BGParseManager::GetNextCookie();\n+\n+    Assert(fullPath != nullptr);\n+    this->path = SysAllocString(fullPath);\n+}\n+\n+BGParseWorkItem::~BGParseWorkItem()\n+{\n+    SysFreeString(this->path);\n+    if (this->complete != nullptr)\n+    {\n+        HeapDelete(this->complete);\n+    }\n+}\n+\n+void BGParseWorkItem::TransferCSE(CompileScriptException* pse)\n+{\n+    this->cse.CopyInto(pse);\n+}\n+\n+// This function parses the input data cached in BGParseWorkItem and caches the\n+// seralized bytecode\n+// Note: runs on BackgroundJobProcessor thread\n+// Note: All exceptions are caught by BackgroundJobProcessor\n+void BGParseWorkItem::ParseUTF8Core(Js::ScriptContext* scriptContext)\n+{\n+    if (PHASE_TRACE1(Js::BgParsePhase))\n+    {\n+        Js::Tick now = Js::Tick::Now();\n+        Output::Print(\n+            _u(\"[BgParse: Parse -- cookie: %04d on thread 0x%X at %.2f ms]\\n\"),\n+            GetCookie(),\n+            ::GetCurrentThreadId(),\n+            now.ToMilliseconds()\n+        );\n+    }\n+\n+    Js::AutoDynamicCodeReference dynamicFunctionReference(scriptContext);\n+    SourceContextInfo* sourceContextInfo = scriptContext->GetSourceContextInfo(this->cookie, nullptr);\n+    if (sourceContextInfo == nullptr)\n+    {\n+        sourceContextInfo = scriptContext->CreateSourceContextInfo(this->cookie, this->path, wcslen(this->path), nullptr);\n+    }\n+\n+    SRCINFO si = {\n+        /* sourceContextInfo   */ sourceContextInfo,\n+        /* dlnHost             */ 0,\n+        /* ulColumnHost        */ 0,\n+        /* lnMinHost           */ 0,\n+        /* ichMinHost          */ 0,\n+        /* ichLimHost          */ (ULONG)0,\n+        /* ulCharOffset        */ 0,\n+        /* mod                 */ 0,\n+        /* grfsi               */ 0\n+    };\n+\n+    // Currently always called from a try-catch\n+    ENTER_PINNED_SCOPE(Js::Utf8SourceInfo, sourceInfo);\n+    sourceInfo = Js::Utf8SourceInfo::NewWithNoCopy(scriptContext, (LPUTF8)this->script, (int32)this->cb, static_cast<int32>(this->cb), &si, false);\n+    LEAVE_PINNED_SCOPE();\n+\n+    // what's a better name for \"fIsOriginalUtf8Source?\" what if i want to say \"isutf8source\" but not \"isoriginal\"?\n+    charcount_t cchLength = 0;\n+    uint sourceIndex = 0;\n+    Js::ParseableFunctionInfo * func = nullptr;\n+    this->parseHR = scriptContext->CompileUTF8Core(sourceInfo, &si, true, this->script, this->cb, 0x1000, &this->cse, cchLength, this->parseSourceLength, sourceIndex, &func);","path":"lib/Parser/BGParseManager.cpp","position":407,"original_position":407,"commit_id":"571518ec0afe490d2f2bb0ef3582070e742875e9","original_commit_id":"571518ec0afe490d2f2bb0ef3582070e742875e9","user":{"login":"sethbrenith","id":828701,"avatar_url":"https://avatars2.githubusercontent.com/u/828701?v=4","gravatar_id":"","url":"https://api.github.com/users/sethbrenith","html_url":"https://github.com/sethbrenith","followers_url":"https://api.github.com/users/sethbrenith/followers","following_url":"https://api.github.com/users/sethbrenith/following{/other_user}","gists_url":"https://api.github.com/users/sethbrenith/gists{/gist_id}","starred_url":"https://api.github.com/users/sethbrenith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sethbrenith/subscriptions","organizations_url":"https://api.github.com/users/sethbrenith/orgs","repos_url":"https://api.github.com/users/sethbrenith/repos","events_url":"https://api.github.com/users/sethbrenith/events{/privacy}","received_events_url":"https://api.github.com/users/sethbrenith/received_events","type":"User","site_admin":false},"body":">0x1000 [](start = 98, length = 6)\r\n\r\nCould we use the name of this value instead of the value directly? Looks like this is `fscrGlobalCode` unless I'm misinterpreting the usage.","created_at":"2018-04-30T18:49:03Z","updated_at":"2018-04-30T18:49:03Z","html_url":"https://github.com/Microsoft/ChakraCore/pull/5058#discussion_r185074571","pull_request_url":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/comments/185074571"},"html":{"href":"https://github.com/Microsoft/ChakraCore/pull/5058#discussion_r185074571"},"pull_request":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058"}}},"pull_request":{"url":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058","id":184705906,"html_url":"https://github.com/Microsoft/ChakraCore/pull/5058","diff_url":"https://github.com/Microsoft/ChakraCore/pull/5058.diff","patch_url":"https://github.com/Microsoft/ChakraCore/pull/5058.patch","issue_url":"https://api.github.com/repos/Microsoft/ChakraCore/issues/5058","number":5058,"state":"open","locked":false,"title":"Initial commit for BGParseManager","user":{"login":"thomasmo","id":16140819,"avatar_url":"https://avatars1.githubusercontent.com/u/16140819?v=4","gravatar_id":"","url":"https://api.github.com/users/thomasmo","html_url":"https://github.com/thomasmo","followers_url":"https://api.github.com/users/thomasmo/followers","following_url":"https://api.github.com/users/thomasmo/following{/other_user}","gists_url":"https://api.github.com/users/thomasmo/gists{/gist_id}","starred_url":"https://api.github.com/users/thomasmo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thomasmo/subscriptions","organizations_url":"https://api.github.com/users/thomasmo/orgs","repos_url":"https://api.github.com/users/thomasmo/repos","events_url":"https://api.github.com/users/thomasmo/events{/privacy}","received_events_url":"https://api.github.com/users/thomasmo/received_events","type":"User","site_admin":false},"body":"Initial commit for BGParseManager.\r\nBGParseManager is responsible for handling and managing requests to parse scripts on a background thread. This work is tracked by the BGParseWorkItem with a cookie, and is managed by BackgroundJobProcessor. The results of the background work is marshaled across threads through bytecode serialization.More details in the header file for BGParseManager.\r\n\r\nThis work can be controlled by a new config flag, BgParse; additional tracing at runtime is also managed by the same flag;","created_at":"2018-04-27T19:18:50Z","updated_at":"2018-04-30T18:49:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"43a46d9fbf1887ee75289390363b9003518c84df","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058/commits","review_comments_url":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058/comments","review_comment_url":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Microsoft/ChakraCore/issues/5058/comments","statuses_url":"https://api.github.com/repos/Microsoft/ChakraCore/statuses/571518ec0afe490d2f2bb0ef3582070e742875e9","head":{"label":"thomasmo:bgparse_intro","ref":"bgparse_intro","sha":"571518ec0afe490d2f2bb0ef3582070e742875e9","user":{"login":"thomasmo","id":16140819,"avatar_url":"https://avatars1.githubusercontent.com/u/16140819?v=4","gravatar_id":"","url":"https://api.github.com/users/thomasmo","html_url":"https://github.com/thomasmo","followers_url":"https://api.github.com/users/thomasmo/followers","following_url":"https://api.github.com/users/thomasmo/following{/other_user}","gists_url":"https://api.github.com/users/thomasmo/gists{/gist_id}","starred_url":"https://api.github.com/users/thomasmo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thomasmo/subscriptions","organizations_url":"https://api.github.com/users/thomasmo/orgs","repos_url":"https://api.github.com/users/thomasmo/repos","events_url":"https://api.github.com/users/thomasmo/events{/privacy}","received_events_url":"https://api.github.com/users/thomasmo/received_events","type":"User","site_admin":false},"repo":{"id":86519363,"name":"ChakraCore","full_name":"thomasmo/ChakraCore","owner":{"login":"thomasmo","id":16140819,"avatar_url":"https://avatars1.githubusercontent.com/u/16140819?v=4","gravatar_id":"","url":"https://api.github.com/users/thomasmo","html_url":"https://github.com/thomasmo","followers_url":"https://api.github.com/users/thomasmo/followers","following_url":"https://api.github.com/users/thomasmo/following{/other_user}","gists_url":"https://api.github.com/users/thomasmo/gists{/gist_id}","starred_url":"https://api.github.com/users/thomasmo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thomasmo/subscriptions","organizations_url":"https://api.github.com/users/thomasmo/orgs","repos_url":"https://api.github.com/users/thomasmo/repos","events_url":"https://api.github.com/users/thomasmo/events{/privacy}","received_events_url":"https://api.github.com/users/thomasmo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/thomasmo/ChakraCore","description":"ChakraCore is the core part of the Chakra Javascript engine that powers Microsoft Edge","fork":true,"url":"https://api.github.com/repos/thomasmo/ChakraCore","forks_url":"https://api.github.com/repos/thomasmo/ChakraCore/forks","keys_url":"https://api.github.com/repos/thomasmo/ChakraCore/keys{/key_id}","collaborators_url":"https://api.github.com/repos/thomasmo/ChakraCore/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/thomasmo/ChakraCore/teams","hooks_url":"https://api.github.com/repos/thomasmo/ChakraCore/hooks","issue_events_url":"https://api.github.com/repos/thomasmo/ChakraCore/issues/events{/number}","events_url":"https://api.github.com/repos/thomasmo/ChakraCore/events","assignees_url":"https://api.github.com/repos/thomasmo/ChakraCore/assignees{/user}","branches_url":"https://api.github.com/repos/thomasmo/ChakraCore/branches{/branch}","tags_url":"https://api.github.com/repos/thomasmo/ChakraCore/tags","blobs_url":"https://api.github.com/repos/thomasmo/ChakraCore/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/thomasmo/ChakraCore/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/thomasmo/ChakraCore/git/refs{/sha}","trees_url":"https://api.github.com/repos/thomasmo/ChakraCore/git/trees{/sha}","statuses_url":"https://api.github.com/repos/thomasmo/ChakraCore/statuses/{sha}","languages_url":"https://api.github.com/repos/thomasmo/ChakraCore/languages","stargazers_url":"https://api.github.com/repos/thomasmo/ChakraCore/stargazers","contributors_url":"https://api.github.com/repos/thomasmo/ChakraCore/contributors","subscribers_url":"https://api.github.com/repos/thomasmo/ChakraCore/subscribers","subscription_url":"https://api.github.com/repos/thomasmo/ChakraCore/subscription","commits_url":"https://api.github.com/repos/thomasmo/ChakraCore/commits{/sha}","git_commits_url":"https://api.github.com/repos/thomasmo/ChakraCore/git/commits{/sha}","comments_url":"https://api.github.com/repos/thomasmo/ChakraCore/comments{/number}","issue_comment_url":"https://api.github.com/repos/thomasmo/ChakraCore/issues/comments{/number}","contents_url":"https://api.github.com/repos/thomasmo/ChakraCore/contents/{+path}","compare_url":"https://api.github.com/repos/thomasmo/ChakraCore/compare/{base}...{head}","merges_url":"https://api.github.com/repos/thomasmo/ChakraCore/merges","archive_url":"https://api.github.com/repos/thomasmo/ChakraCore/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/thomasmo/ChakraCore/downloads","issues_url":"https://api.github.com/repos/thomasmo/ChakraCore/issues{/number}","pulls_url":"https://api.github.com/repos/thomasmo/ChakraCore/pulls{/number}","milestones_url":"https://api.github.com/repos/thomasmo/ChakraCore/milestones{/number}","notifications_url":"https://api.github.com/repos/thomasmo/ChakraCore/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/thomasmo/ChakraCore/labels{/name}","releases_url":"https://api.github.com/repos/thomasmo/ChakraCore/releases{/id}","deployments_url":"https://api.github.com/repos/thomasmo/ChakraCore/deployments","created_at":"2017-03-29T00:04:51Z","updated_at":"2017-03-29T00:05:10Z","pushed_at":"2018-04-30T17:36:40Z","git_url":"git://github.com/thomasmo/ChakraCore.git","ssh_url":"git@github.com:thomasmo/ChakraCore.git","clone_url":"https://github.com/thomasmo/ChakraCore.git","svn_url":"https://github.com/thomasmo/ChakraCore","homepage":"","size":122057,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Microsoft:master","ref":"master","sha":"71d8d72e5c091dd94cd70537ad045d3fa80094a2","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars2.githubusercontent.com/u/6154722?v=4","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":49086513,"name":"ChakraCore","full_name":"Microsoft/ChakraCore","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars2.githubusercontent.com/u/6154722?v=4","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/ChakraCore","description":"ChakraCore is the core part of the Chakra Javascript engine that powers Microsoft Edge","fork":false,"url":"https://api.github.com/repos/Microsoft/ChakraCore","forks_url":"https://api.github.com/repos/Microsoft/ChakraCore/forks","keys_url":"https://api.github.com/repos/Microsoft/ChakraCore/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/ChakraCore/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/ChakraCore/teams","hooks_url":"https://api.github.com/repos/Microsoft/ChakraCore/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/ChakraCore/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/ChakraCore/events","assignees_url":"https://api.github.com/repos/Microsoft/ChakraCore/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/ChakraCore/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/ChakraCore/tags","blobs_url":"https://api.github.com/repos/Microsoft/ChakraCore/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/ChakraCore/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/ChakraCore/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/ChakraCore/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/ChakraCore/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/ChakraCore/languages","stargazers_url":"https://api.github.com/repos/Microsoft/ChakraCore/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/ChakraCore/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/ChakraCore/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/ChakraCore/subscription","commits_url":"https://api.github.com/repos/Microsoft/ChakraCore/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/ChakraCore/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/ChakraCore/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/ChakraCore/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/ChakraCore/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/ChakraCore/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/ChakraCore/merges","archive_url":"https://api.github.com/repos/Microsoft/ChakraCore/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/ChakraCore/downloads","issues_url":"https://api.github.com/repos/Microsoft/ChakraCore/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/ChakraCore/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/ChakraCore/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/ChakraCore/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/ChakraCore/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/ChakraCore/releases{/id}","deployments_url":"https://api.github.com/repos/Microsoft/ChakraCore/deployments","created_at":"2016-01-05T19:05:31Z","updated_at":"2018-04-30T18:25:16Z","pushed_at":"2018-04-30T18:42:08Z","git_url":"git://github.com/Microsoft/ChakraCore.git","ssh_url":"git@github.com:Microsoft/ChakraCore.git","clone_url":"https://github.com/Microsoft/ChakraCore.git","svn_url":"https://github.com/Microsoft/ChakraCore","homepage":"","size":127761,"stargazers_count":6956,"watchers_count":6956,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":914,"mirror_url":null,"archived":false,"open_issues_count":337,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":914,"open_issues":337,"watchers":6956,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058"},"html":{"href":"https://github.com/Microsoft/ChakraCore/pull/5058"},"issue":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/issues/5058"},"comments":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/issues/5058/comments"},"review_comments":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058/comments"},"review_comment":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/pulls/5058/commits"},"statuses":{"href":"https://api.github.com/repos/Microsoft/ChakraCore/statuses/571518ec0afe490d2f2bb0ef3582070e742875e9"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"sethbrenith"}}