{"action":"created","comment":{"url":"https://api.github.com/repos/ldc-developers/druntime/pulls/comments/37818148","id":37818148,"diff_hunk":"@@ -0,0 +1,650 @@\n+/**\n+ * This module contains functions and structures required for exception\n+ * handling which are shared by platform-specific implementations.\n+ */\n+module ldc.eh.common;\n+\n+// debug = EH_personality;\n+// debug = EH_personality_verbose;\n+\n+import core.memory : GC;\n+import core.stdc.stdio;\n+import core.stdc.stdlib;\n+import core.stdc.stdarg;\n+\n+// D runtime function\n+extern(C) int _d_isbaseof(ClassInfo oc, ClassInfo c);\n+\n+// error and exit\n+extern(C) void fatalerror(in char* format, ...)\n+{\n+    va_list args;\n+    va_start(args, format);\n+    fprintf(stderr, \"Fatal error in EH code: \");\n+    vfprintf(stderr, format, args);\n+    fprintf(stderr, \"\\n\");\n+    abort();\n+}\n+\n+// ------------------------\n+//    Reading DWARF data\n+// ------------------------\n+\n+version (Win64) {} else\n+{\n+    extern(C)\n+    {\n+        alias void* _Unwind_Context_Ptr;\n+        ptrdiff_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context);\n+        ptrdiff_t _Unwind_GetTextRelBase(_Unwind_Context_Ptr context);\n+        ptrdiff_t _Unwind_GetDataRelBase(_Unwind_Context_Ptr context);\n+    }\n+}\n+\n+enum _DW_EH_Format : int\n+{\n+    DW_EH_PE_absptr  = 0x00,  // The Value is a literal pointer whose size is determined by the architecture.\n+    DW_EH_PE_uleb128 = 0x01,  // Unsigned value is encoded using the Little Endian Base 128 (LEB128)\n+    DW_EH_PE_udata2  = 0x02,  // A 2 bytes unsigned value.\n+    DW_EH_PE_udata4  = 0x03,  // A 4 bytes unsigned value.\n+    DW_EH_PE_udata8  = 0x04,  // An 8 bytes unsigned value.\n+    DW_EH_PE_sleb128 = 0x09,  // Signed value is encoded using the Little Endian Base 128 (LEB128)\n+    DW_EH_PE_sdata2  = 0x0A,  // A 2 bytes signed value.\n+    DW_EH_PE_sdata4  = 0x0B,  // A 4 bytes signed value.\n+    DW_EH_PE_sdata8  = 0x0C,  // An 8 bytes signed value.\n+\n+    DW_EH_PE_pcrel   = 0x10,  // Value is relative to the current program counter.\n+    DW_EH_PE_textrel = 0x20,  // Value is relative to the beginning of the .text section.\n+    DW_EH_PE_datarel = 0x30,  // Value is relative to the beginning of the .got or .eh_frame_hdr section.\n+    DW_EH_PE_funcrel = 0x40,  // Value is relative to the beginning of the function.\n+    DW_EH_PE_aligned = 0x50,  // Value is aligned to an address unit sized boundary.\n+\n+    DW_EH_PE_indirect = 0x80,\n+\n+    DW_EH_PE_omit    = 0xff   // Indicates that no value is present.\n+}\n+\n+ubyte* get_uleb128(ubyte* addr, ref size_t res)\n+{\n+    res = 0;\n+    size_t bitsize = 0;\n+\n+    // read as long as high bit is set\n+    while(*addr & 0x80)\n+    {\n+        res |= (*addr & 0x7f) << bitsize;\n+        bitsize += 7;\n+        addr += 1;\n+        if (bitsize >= size_t.sizeof*8)\n+            fatalerror(\"tried to read uleb128 that exceeded size of size_t\");\n+    }\n+    // read last\n+    if (bitsize != 0 && *addr >= 1L << size_t.sizeof*8 - bitsize)\n+        fatalerror(\"tried to read uleb128 that exceeded size of size_t\");\n+    res |= (*addr) << bitsize;\n+\n+    return addr + 1;\n+}\n+\n+ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res)\n+{\n+    res = 0;\n+    size_t bitsize = 0;\n+\n+    // read as long as high bit is set\n+    while (*addr & 0x80)\n+    {\n+        res |= (*addr & 0x7f) << bitsize;\n+        bitsize += 7;\n+        addr += 1;\n+        if (bitsize >= size_t.sizeof*8)\n+            fatalerror(\"tried to read sleb128 that exceeded size of size_t\");\n+    }\n+    // read last\n+    if (bitsize != 0 && *addr >= 1L << size_t.sizeof*8 - bitsize)\n+        fatalerror(\"tried to read sleb128 that exceeded size of size_t\");\n+    res |= (*addr) << bitsize;\n+\n+    // take care of sign\n+    if (bitsize < size_t.sizeof*8 && ((*addr) & 0x40))\n+        res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1);\n+\n+    return addr + 1;\n+}\n+\n+size_t get_size_of_encoded_value(ubyte encoding)\n+{\n+    if (encoding == _DW_EH_Format.DW_EH_PE_omit)\n+        return 0;\n+\n+    switch (encoding & 0x07)\n+    {\n+        case _DW_EH_Format.DW_EH_PE_absptr:\n+            return size_t.sizeof;\n+        case _DW_EH_Format.DW_EH_PE_udata2:\n+            return 2;\n+        case _DW_EH_Format.DW_EH_PE_udata4:\n+            return 4;\n+        case _DW_EH_Format.DW_EH_PE_udata8:\n+            return 8;\n+        default:\n+            fatalerror(\"Unsupported DWARF Exception Header value format: unknown encoding\");\n+    }\n+    assert(0);\n+}\n+\n+ubyte* get_encoded_value(ubyte* addr, ref size_t res, ubyte encoding, void* context)\n+{\n+    ubyte *old_addr = addr;\n+\n+    if (encoding == _DW_EH_Format.DW_EH_PE_aligned)\n+        goto Lerr;\n+\n+    switch (encoding & 0x0f)\n+    {\n+      case _DW_EH_Format.DW_EH_PE_absptr:\n+          res = cast(size_t)*cast(ubyte**)addr;\n+          addr += size_t.sizeof;\n+          break;\n+\n+      case _DW_EH_Format.DW_EH_PE_uleb128:\n+          addr = get_uleb128(addr, res);\n+          break;\n+\n+      case _DW_EH_Format.DW_EH_PE_sleb128:\n+          ptrdiff_t r;\n+          addr = get_sleb128(addr, r);\n+          r = cast(size_t)res;\n+          break;\n+\n+      case _DW_EH_Format.DW_EH_PE_udata2:\n+          res = *cast(ushort*)addr;\n+          addr += 2;\n+          break;\n+      case _DW_EH_Format.DW_EH_PE_udata4:\n+          res = *cast(uint*)addr;\n+          addr += 4;\n+          break;\n+      case _DW_EH_Format.DW_EH_PE_udata8:\n+          res = cast(size_t)*cast(ulong*)addr;\n+          addr += 8;\n+          break;\n+\n+      case _DW_EH_Format.DW_EH_PE_sdata2:\n+          res = *cast(short*)addr;\n+          addr += 2;\n+          break;\n+      case _DW_EH_Format.DW_EH_PE_sdata4:\n+          res = *cast(int*)addr;\n+          addr += 4;\n+          break;\n+      case _DW_EH_Format.DW_EH_PE_sdata8:\n+          res = cast(size_t)*cast(long*)addr;\n+          addr += 8;\n+          break;\n+\n+      default:\n+          goto Lerr;\n+    }\n+\n+    switch (encoding & 0x70)\n+    {\n+        case _DW_EH_Format.DW_EH_PE_absptr:\n+            break;\n+        case _DW_EH_Format.DW_EH_PE_pcrel:\n+            res += cast(size_t)old_addr;\n+            break;\n+        case _DW_EH_Format.DW_EH_PE_funcrel:\n+            version(Win64) fatalerror(\"Not yet implemented.\"); else\n+            res += cast(size_t)_Unwind_GetRegionStart(context);\n+            break;\n+        case _DW_EH_Format.DW_EH_PE_textrel:\n+            version(Win64) fatalerror(\"Not yet implemented.\"); else\n+            res += cast(size_t)_Unwind_GetTextRelBase(context);\n+            break;\n+        case _DW_EH_Format.DW_EH_PE_datarel:\n+            version(Win64) fatalerror(\"Not yet implemented.\"); else\n+            res += cast(size_t)_Unwind_GetDataRelBase(context);\n+            break;\n+        default:\n+            goto Lerr;\n+    }\n+\n+    if (encoding & _DW_EH_Format.DW_EH_PE_indirect)\n+        res = cast(size_t)*cast(void**)res;\n+\n+    return addr;\n+\n+Lerr:\n+    fatalerror(\"Unsupported DWARF Exception Header value format\");\n+    return addr;\n+}\n+\n+ptrdiff_t get_base_of_encoded_value(ubyte encoding, void* context)\n+{\n+    if (encoding == _DW_EH_Format.DW_EH_PE_omit)\n+        return 0;\n+\n+    with (_DW_EH_Format) switch (encoding & 0x70) {\n+        case DW_EH_PE_absptr:\n+        case DW_EH_PE_pcrel:\n+        case DW_EH_PE_aligned:\n+            return 0;\n+\n+      version(Win64) {} else\n+      {\n+        case DW_EH_PE_textrel:\n+            return _Unwind_GetTextRelBase (context);\n+        case DW_EH_PE_datarel:\n+            return _Unwind_GetDataRelBase (context);\n+        case DW_EH_PE_funcrel:\n+            return _Unwind_GetRegionStart (context);\n+      }\n+\n+        default:\n+            fatalerror(\"Unsupported encoding type to get base from.\");\n+            assert(0);\n+    }\n+}\n+\n+void _d_getLanguageSpecificTables(ubyte* data, ref ubyte* callsite, ref ubyte* action, ref ubyte* classinfo_table, ref ubyte ciEncoding)\n+{\n+    if (data is null)\n+    {\n+        debug(EH_personality) printf(\"language specific data was null\\n\");\n+        callsite = null;\n+        action = null;\n+        classinfo_table = null;\n+        return;\n+    }\n+    debug(EH_personality) printf(\"  - LSDA: %p\\n\", data);\n+\n+    //TODO: Do proper DWARF reading here\n+    if (*data++ != _DW_EH_Format.DW_EH_PE_omit)\n+        fatalerror(\"DWARF header has unexpected format 1\");\n+\n+    ciEncoding = *data++;\n+    if (ciEncoding == _DW_EH_Format.DW_EH_PE_omit)\n+        fatalerror(\"Language Specific Data does not contain Types Table\");\n+    version (ARM) version (linux) {\n+        with (_DW_EH_Format) {\n+            ciEncoding = DW_EH_PE_pcrel | DW_EH_PE_indirect;\n+        }\n+    }\n+\n+    size_t cioffset;\n+    data = get_uleb128(data, cioffset);\n+    classinfo_table = data + cioffset;\n+\n+    if (*data++ != _DW_EH_Format.DW_EH_PE_udata4)\n+        fatalerror(\"DWARF header has unexpected format 2\");\n+    size_t callsitelength;\n+    data = get_uleb128(data, callsitelength);\n+    action = data + callsitelength;\n+\n+    callsite = data;\n+\n+    debug(EH_personality) printf(\"  - callsite: %p, action: %p, classinfo_table: %p, ciEncoding: %d\\n\", callsite, action, classinfo_table, ciEncoding);\n+}\n+\n+\n+\n+// -----------------------------\n+//    Stack of finally blocks\n+// -----------------------------\n+\n+struct ActiveCleanupBlock {\n+    /// Link to the next active finally block.\n+    ActiveCleanupBlock* outerBlock;\n+\n+    /// The exception that caused this cleanup block to be entered.\n+    Object dObject;\n+\n+    /// The CFA (stack address, roughly) when this cleanup block was entered, as\n+    /// reported by libunwind.\n+    ///\n+    /// Used to determine when this pad is reached again when unwinding from\n+    /// somewhere within it. Note that this must somehow be related to the\n+    /// stack, not the instruction pointer, to properly support recursive\n+    /// chaining.\n+    ptrdiff_t cfaAddr;\n+}\n+\n+/// Stack of active finally blocks (i.e. cleanup landing pads) that were entered\n+/// because of exception unwinding. Used for exception chaining.\n+///\n+/// Note that sometimes a landing pad is both a catch and a cleanup. This\n+/// happens for example when there is a try/finally nested inside a try/catch\n+/// in the same function, or has been inlined into one. Whether a catch will\n+/// actually execute (which terminates this strand of unwinding) or not is\n+/// determined by the program code and cannot be known inside the personality\n+/// routine. Thus, we always push such a block even before entering a catch(),\n+/// and have the user code call _d_eh_enter_catch() once the (possible) cleanup\n+/// part is done so we can pop it again. In theory, this could be optimized a\n+/// bit, because we only need to do it for landing pads which have this double\n+/// function, which we could possibly figure out form the DWARF tables. However,\n+/// since this makes generating the code for popping it non-trivial, this is not\n+/// currently done.\n+ActiveCleanupBlock* innermostCleanupBlock = null;\n+\n+/// During the search phase of unwinding, points to the currently active cleanup\n+/// block (i.e. somewhere in the innermostCleanupBlock linked list, but possibly\n+/// not at the beginning if the search for the catch block has already continued\n+/// past that).\n+///\n+/// Note that this and searchPhaseCurrentCleanupBlock can just be a single\n+/// variable because there can never be more than one search phase running per\n+/// thread.\n+ActiveCleanupBlock* searchPhaseCurrentCleanupBlock = null;\n+\n+/// During the search phase, keeps track of the type of the dynamic type of the\n+/// currently thrown exception (might change according to exception chaining\n+/// rules).\n+ClassInfo searchPhaseClassInfo = null;\n+\n+void pushCleanupBlockRecord(ptrdiff_t cfaAddr, Object dObject)\n+{\n+    auto acb = cast(ActiveCleanupBlock*)malloc(ActiveCleanupBlock.sizeof);\n+    if (!acb)\n+    {\n+        // TODO: Allocate some statically to avoid problem with unwinding out of\n+        // memory errors. A fairly small amount of memory should suffice for\n+        // most applications unless people want to unwind through very deeply\n+        // recursive code with many finally blocks.\n+        fatalerror(\"Could not allocate memory for exception chaining.\");\n+    }\n+    acb.cfaAddr = cfaAddr;\n+    acb.dObject = dObject;\n+    acb.outerBlock = innermostCleanupBlock;\n+    innermostCleanupBlock = acb;\n+\n+    // We need to be sure that an in-flight exception is kept alive while\n+    // executing a finally block. This is not automatically the case if the\n+    // finally block always throws, because the compiler then does not need to\n+    // keep a reference to the object extracted from the landing pad around as\n+    // there is no _d_eh_resume_unwind() call.\n+    GC.addRoot(cast(void*)dObject);\n+}\n+\n+void popCleanupBlockRecord()\n+{\n+    if (!innermostCleanupBlock)\n+    {\n+        fatalerror(\"No cleanup block record found, should have been pushed \" ~\n+            \"before entering the finally block.\");\n+    }\n+    // Remove the cleanup block we installed for this handler.\n+    auto acb = innermostCleanupBlock;\n+    GC.removeRoot(cast(void*)acb.dObject);\n+    innermostCleanupBlock = acb.outerBlock;\n+    free(acb);\n+}\n+\n+\n+\n+/// This is the implementation of the personality function, which is called by\n+/// libunwind twice per frame (search phase, unwind phase).\n+///\n+/// It is responsible to figure out whether we need to stop unwinding because of\n+/// a catch block or if there is a finally block to execute by reading the DWARF\n+/// EH tables.\n+extern(C) auto eh_personality_common(NativeContext)(ref NativeContext nativeContext)","path":"src/ldc/eh/common.d","position":391,"original_position":391,"commit_id":"82331a27b20987de6d9f07eeb47708c139a7ae45","original_commit_id":"82331a27b20987de6d9f07eeb47708c139a7ae45","user":{"login":"kinke","id":1889215,"avatar_url":"https://avatars.githubusercontent.com/u/1889215?v=3","gravatar_id":"","url":"https://api.github.com/users/kinke","html_url":"https://github.com/kinke","followers_url":"https://api.github.com/users/kinke/followers","following_url":"https://api.github.com/users/kinke/following{/other_user}","gists_url":"https://api.github.com/users/kinke/gists{/gist_id}","starred_url":"https://api.github.com/users/kinke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kinke/subscriptions","organizations_url":"https://api.github.com/users/kinke/orgs","repos_url":"https://api.github.com/users/kinke/repos","events_url":"https://api.github.com/users/kinke/events{/privacy}","received_events_url":"https://api.github.com/users/kinke/received_events","type":"User","site_admin":false},"body":"It already was `extern(C)`, I've just copy&pasted it.","created_at":"2015-08-24T23:39:19Z","updated_at":"2015-08-24T23:39:19Z","html_url":"https://github.com/ldc-developers/druntime/pull/31#discussion_r37818148","pull_request_url":"https://api.github.com/repos/ldc-developers/druntime/pulls/31","_links":{"self":{"href":"https://api.github.com/repos/ldc-developers/druntime/pulls/comments/37818148"},"html":{"href":"https://github.com/ldc-developers/druntime/pull/31#discussion_r37818148"},"pull_request":{"href":"https://api.github.com/repos/ldc-developers/druntime/pulls/31"}}},"pull_request":{"url":"https://api.github.com/repos/ldc-developers/druntime/pulls/31","id":43110662,"html_url":"https://github.com/ldc-developers/druntime/pull/31","diff_url":"https://github.com/ldc-developers/druntime/pull/31.diff","patch_url":"https://github.com/ldc-developers/druntime/pull/31.patch","issue_url":"https://api.github.com/repos/ldc-developers/druntime/issues/31","number":31,"state":"closed","locked":false,"title":"Adapt Win64 EH to recent LDC EH rewrite and refactor EH into ldc.eh package","user":{"login":"kinke","id":1889215,"avatar_url":"https://avatars.githubusercontent.com/u/1889215?v=3","gravatar_id":"","url":"https://api.github.com/users/kinke","html_url":"https://github.com/kinke","followers_url":"https://api.github.com/users/kinke/followers","following_url":"https://api.github.com/users/kinke/following{/other_user}","gists_url":"https://api.github.com/users/kinke/gists{/gist_id}","starred_url":"https://api.github.com/users/kinke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kinke/subscriptions","organizations_url":"https://api.github.com/users/kinke/orgs","repos_url":"https://api.github.com/users/kinke/repos","events_url":"https://api.github.com/users/kinke/events{/privacy}","received_events_url":"https://api.github.com/users/kinke/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-08-22T21:33:34Z","updated_at":"2015-08-24T23:39:19Z","closed_at":"2015-08-24T23:34:42Z","merged_at":"2015-08-24T23:34:42Z","merge_commit_sha":"4e627642f5f597270d824cd88dec674a8f618929","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ldc-developers/druntime/pulls/31/commits","review_comments_url":"https://api.github.com/repos/ldc-developers/druntime/pulls/31/comments","review_comment_url":"https://api.github.com/repos/ldc-developers/druntime/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ldc-developers/druntime/issues/31/comments","statuses_url":"https://api.github.com/repos/ldc-developers/druntime/statuses/82331a27b20987de6d9f07eeb47708c139a7ae45","head":{"label":"kinke:eh2","ref":"eh2","sha":"82331a27b20987de6d9f07eeb47708c139a7ae45","user":{"login":"kinke","id":1889215,"avatar_url":"https://avatars.githubusercontent.com/u/1889215?v=3","gravatar_id":"","url":"https://api.github.com/users/kinke","html_url":"https://github.com/kinke","followers_url":"https://api.github.com/users/kinke/followers","following_url":"https://api.github.com/users/kinke/following{/other_user}","gists_url":"https://api.github.com/users/kinke/gists{/gist_id}","starred_url":"https://api.github.com/users/kinke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kinke/subscriptions","organizations_url":"https://api.github.com/users/kinke/orgs","repos_url":"https://api.github.com/users/kinke/repos","events_url":"https://api.github.com/users/kinke/events{/privacy}","received_events_url":"https://api.github.com/users/kinke/received_events","type":"User","site_admin":false},"repo":{"id":7736439,"name":"druntime","full_name":"kinke/druntime","owner":{"login":"kinke","id":1889215,"avatar_url":"https://avatars.githubusercontent.com/u/1889215?v=3","gravatar_id":"","url":"https://api.github.com/users/kinke","html_url":"https://github.com/kinke","followers_url":"https://api.github.com/users/kinke/followers","following_url":"https://api.github.com/users/kinke/following{/other_user}","gists_url":"https://api.github.com/users/kinke/gists{/gist_id}","starred_url":"https://api.github.com/users/kinke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kinke/subscriptions","organizations_url":"https://api.github.com/users/kinke/orgs","repos_url":"https://api.github.com/users/kinke/repos","events_url":"https://api.github.com/users/kinke/events{/privacy}","received_events_url":"https://api.github.com/users/kinke/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kinke/druntime","description":"MSVCRT and Win64 related fixes.","fork":true,"url":"https://api.github.com/repos/kinke/druntime","forks_url":"https://api.github.com/repos/kinke/druntime/forks","keys_url":"https://api.github.com/repos/kinke/druntime/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kinke/druntime/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kinke/druntime/teams","hooks_url":"https://api.github.com/repos/kinke/druntime/hooks","issue_events_url":"https://api.github.com/repos/kinke/druntime/issues/events{/number}","events_url":"https://api.github.com/repos/kinke/druntime/events","assignees_url":"https://api.github.com/repos/kinke/druntime/assignees{/user}","branches_url":"https://api.github.com/repos/kinke/druntime/branches{/branch}","tags_url":"https://api.github.com/repos/kinke/druntime/tags","blobs_url":"https://api.github.com/repos/kinke/druntime/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kinke/druntime/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kinke/druntime/git/refs{/sha}","trees_url":"https://api.github.com/repos/kinke/druntime/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kinke/druntime/statuses/{sha}","languages_url":"https://api.github.com/repos/kinke/druntime/languages","stargazers_url":"https://api.github.com/repos/kinke/druntime/stargazers","contributors_url":"https://api.github.com/repos/kinke/druntime/contributors","subscribers_url":"https://api.github.com/repos/kinke/druntime/subscribers","subscription_url":"https://api.github.com/repos/kinke/druntime/subscription","commits_url":"https://api.github.com/repos/kinke/druntime/commits{/sha}","git_commits_url":"https://api.github.com/repos/kinke/druntime/git/commits{/sha}","comments_url":"https://api.github.com/repos/kinke/druntime/comments{/number}","issue_comment_url":"https://api.github.com/repos/kinke/druntime/issues/comments{/number}","contents_url":"https://api.github.com/repos/kinke/druntime/contents/{+path}","compare_url":"https://api.github.com/repos/kinke/druntime/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kinke/druntime/merges","archive_url":"https://api.github.com/repos/kinke/druntime/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kinke/druntime/downloads","issues_url":"https://api.github.com/repos/kinke/druntime/issues{/number}","pulls_url":"https://api.github.com/repos/kinke/druntime/pulls{/number}","milestones_url":"https://api.github.com/repos/kinke/druntime/milestones{/number}","notifications_url":"https://api.github.com/repos/kinke/druntime/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kinke/druntime/labels{/name}","releases_url":"https://api.github.com/repos/kinke/druntime/releases{/id}","created_at":"2013-01-21T17:05:22Z","updated_at":"2015-08-08T16:00:21Z","pushed_at":"2015-08-24T22:30:15Z","git_url":"git://github.com/kinke/druntime.git","ssh_url":"git@github.com:kinke/druntime.git","clone_url":"https://github.com/kinke/druntime.git","svn_url":"https://github.com/kinke/druntime","homepage":"","size":9626,"stargazers_count":0,"watchers_count":0,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"win64"}},"base":{"label":"ldc-developers:ldc-merge-2.067","ref":"ldc-merge-2.067","sha":"1615d910efd35ea3b8928e2ea62268ee9ccb10f0","user":{"login":"ldc-developers","id":960112,"avatar_url":"https://avatars.githubusercontent.com/u/960112?v=3","gravatar_id":"","url":"https://api.github.com/users/ldc-developers","html_url":"https://github.com/ldc-developers","followers_url":"https://api.github.com/users/ldc-developers/followers","following_url":"https://api.github.com/users/ldc-developers/following{/other_user}","gists_url":"https://api.github.com/users/ldc-developers/gists{/gist_id}","starred_url":"https://api.github.com/users/ldc-developers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ldc-developers/subscriptions","organizations_url":"https://api.github.com/users/ldc-developers/orgs","repos_url":"https://api.github.com/users/ldc-developers/repos","events_url":"https://api.github.com/users/ldc-developers/events{/privacy}","received_events_url":"https://api.github.com/users/ldc-developers/received_events","type":"Organization","site_admin":false},"repo":{"id":2174491,"name":"druntime","full_name":"ldc-developers/druntime","owner":{"login":"ldc-developers","id":960112,"avatar_url":"https://avatars.githubusercontent.com/u/960112?v=3","gravatar_id":"","url":"https://api.github.com/users/ldc-developers","html_url":"https://github.com/ldc-developers","followers_url":"https://api.github.com/users/ldc-developers/followers","following_url":"https://api.github.com/users/ldc-developers/following{/other_user}","gists_url":"https://api.github.com/users/ldc-developers/gists{/gist_id}","starred_url":"https://api.github.com/users/ldc-developers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ldc-developers/subscriptions","organizations_url":"https://api.github.com/users/ldc-developers/orgs","repos_url":"https://api.github.com/users/ldc-developers/repos","events_url":"https://api.github.com/users/ldc-developers/events{/privacy}","received_events_url":"https://api.github.com/users/ldc-developers/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ldc-developers/druntime","description":"LDC implementation of the D low-level runtime library.","fork":true,"url":"https://api.github.com/repos/ldc-developers/druntime","forks_url":"https://api.github.com/repos/ldc-developers/druntime/forks","keys_url":"https://api.github.com/repos/ldc-developers/druntime/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ldc-developers/druntime/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ldc-developers/druntime/teams","hooks_url":"https://api.github.com/repos/ldc-developers/druntime/hooks","issue_events_url":"https://api.github.com/repos/ldc-developers/druntime/issues/events{/number}","events_url":"https://api.github.com/repos/ldc-developers/druntime/events","assignees_url":"https://api.github.com/repos/ldc-developers/druntime/assignees{/user}","branches_url":"https://api.github.com/repos/ldc-developers/druntime/branches{/branch}","tags_url":"https://api.github.com/repos/ldc-developers/druntime/tags","blobs_url":"https://api.github.com/repos/ldc-developers/druntime/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ldc-developers/druntime/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ldc-developers/druntime/git/refs{/sha}","trees_url":"https://api.github.com/repos/ldc-developers/druntime/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ldc-developers/druntime/statuses/{sha}","languages_url":"https://api.github.com/repos/ldc-developers/druntime/languages","stargazers_url":"https://api.github.com/repos/ldc-developers/druntime/stargazers","contributors_url":"https://api.github.com/repos/ldc-developers/druntime/contributors","subscribers_url":"https://api.github.com/repos/ldc-developers/druntime/subscribers","subscription_url":"https://api.github.com/repos/ldc-developers/druntime/subscription","commits_url":"https://api.github.com/repos/ldc-developers/druntime/commits{/sha}","git_commits_url":"https://api.github.com/repos/ldc-developers/druntime/git/commits{/sha}","comments_url":"https://api.github.com/repos/ldc-developers/druntime/comments{/number}","issue_comment_url":"https://api.github.com/repos/ldc-developers/druntime/issues/comments{/number}","contents_url":"https://api.github.com/repos/ldc-developers/druntime/contents/{+path}","compare_url":"https://api.github.com/repos/ldc-developers/druntime/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ldc-developers/druntime/merges","archive_url":"https://api.github.com/repos/ldc-developers/druntime/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ldc-developers/druntime/downloads","issues_url":"https://api.github.com/repos/ldc-developers/druntime/issues{/number}","pulls_url":"https://api.github.com/repos/ldc-developers/druntime/pulls{/number}","milestones_url":"https://api.github.com/repos/ldc-developers/druntime/milestones{/number}","notifications_url":"https://api.github.com/repos/ldc-developers/druntime/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ldc-developers/druntime/labels{/name}","releases_url":"https://api.github.com/repos/ldc-developers/druntime/releases{/id}","created_at":"2011-08-08T16:36:30Z","updated_at":"2015-07-20T21:19:05Z","pushed_at":"2015-08-24T23:34:42Z","git_url":"git://github.com/ldc-developers/druntime.git","ssh_url":"git@github.com:ldc-developers/druntime.git","clone_url":"https://github.com/ldc-developers/druntime.git","svn_url":"https://github.com/ldc-developers/druntime","homepage":"","size":10641,"stargazers_count":16,"watchers_count":16,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":14,"mirror_url":null,"open_issues_count":4,"forks":14,"open_issues":4,"watchers":16,"default_branch":"ldc"}},"_links":{"self":{"href":"https://api.github.com/repos/ldc-developers/druntime/pulls/31"},"html":{"href":"https://github.com/ldc-developers/druntime/pull/31"},"issue":{"href":"https://api.github.com/repos/ldc-developers/druntime/issues/31"},"comments":{"href":"https://api.github.com/repos/ldc-developers/druntime/issues/31/comments"},"review_comments":{"href":"https://api.github.com/repos/ldc-developers/druntime/pulls/31/comments"},"review_comment":{"href":"https://api.github.com/repos/ldc-developers/druntime/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ldc-developers/druntime/pulls/31/commits"},"statuses":{"href":"https://api.github.com/repos/ldc-developers/druntime/statuses/82331a27b20987de6d9f07eeb47708c139a7ae45"}}}}