// maps:put/3 [21] term_t cbif_put3(proc_t *proc, term_t *regs) { term_t Key = regs[0]; term_t Value = regs[1]; term_t Map = regs[2]; if (!is_boxed_map(Map)) badarg(Map); t_map_t *m0 = (t_map_t *)peel_boxed(Map); int index = map_key_index(Key, m0->keys); if (index >= 0) { // same as update/3 int size = map_size(m0); int needed = WSIZE(t_map_t) +size; uint32_t *p = heap_alloc(&proc->hp, needed); t_map_t *m1 = (t_map_t *)p; box_map(p, size, m0->keys); heap_set_top(&proc->hp, p); memcpy(m1->values, m0->values, size *sizeof(term_t)); m1->values[index] = Value; return tag_boxed(m1); } else { uint32_t *q = peel_tuple(m0->keys); int size = *q++; term_t *ks = q; term_t kvs[] = {Key,Value}; int needed = 1 +size+1 +2 +size+1; uint32_t *p = heap_alloc(&proc->hp, needed); term_t keys = tag_tuple(p); *p++ = size+1; term_t *ks1 = p; p += size+1; term_t out = tag_boxed(p); term_t *vs1 = p +WSIZE(t_map_t); box_map(p, size+1, keys); heap_set_top(&proc->hp, p); int size1 = map_merge(ks, m0->values, size, kvs, 1, ks1, vs1); assert(size1 == size+1); return out; } }
// maps:update/3 [18] term_t cbif_update3(proc_t *proc, term_t *regs) { term_t Key = regs[0]; term_t Value = regs[1]; term_t Map = regs[2]; if (!is_boxed_map(Map)) badarg(Map); t_map_t *m0 = (t_map_t *)peel_boxed(Map); int index = map_key_index(Key, m0->keys); if (index < 0) badarg(Key); int size = map_size(m0); int needed = WSIZE(t_map_t) +size; uint32_t *p = heap_alloc(&proc->hp, needed); t_map_t *m1 = (t_map_t *)p; box_map(p, size, m0->keys); heap_set_top(&proc->hp, p); memcpy(m1->values, m0->values, size *sizeof(term_t)); m1->values[index] = Value; return tag_boxed(m1); }
VOID WmChar(WPARAM Char) { static WCHAR Hold[10]; if (!Disabled) { if (Interruptable) { #if defined(WIN32) switch (Char) { case CTRL('s'): XOffState = TRUE; LOADSTRINGW(hInst, 914, Hold, WSIZE(Hold)); NewStatus(1, Hold, NS_NORMAL); break; case CTRL('c'): Interrupted = TRUE; ExecInterrupt(CTRL_C_EVENT); /*FALLTHROUGH*/ case CTRL('q'): XOffState = FALSE; NewStatus(1, L"", NS_NORMAL); ReleaseXOff(); break; } #endif } else GotChar(Char, 0); } else if (Char == CTRL('c')) #if defined(WIN32) Interrupted = CTRL_C_EVENT+1; #else Interrupted = TRUE; #endif }
uint32_t *ets_terms_copy_non_recursive_N(term_t *terms, int num, uint32_t *htop, t_proc_bin_t **pbs) { uint32_t cradle[256]; stack_t st; stack_init(&st, WSIZE(ets_deferred_copy_t), cradle, 256); uint32_t *last_htop = terms_copy(&st, terms, num, htop, pbs); stack_done(&st); return last_htop; }
void ReplaceSearched(HWND hDlg) { MODEENUM SaveMode = Mode; LONG Length; Magic = IsDlgButtonChecked(hDlg, IDC_MAGIC); HexInput = IsDlgButtonChecked(hDlg, IDC_HEXSEARCH); GetDlgItemTextW(hDlg, IDC_REPLACESTRING, CommandBuf, WSIZE(CommandBuf)); hwndErrorParent = hDlg; /*change parent of message box*/ if ((Magic && !CheckParenPairs()) || !BuildReplaceString(CommandBuf, &Length, &CurrPos, SelectCount, (WORD)(HexInput | 2 | (Magic ? 0 : 4)))) { hwndErrorParent = hwndMain; /*change parent of message box*/ return; } hwndErrorParent = hwndMain; /*change parent of message box*/ Mode = InsertMode; StartUndoSequence(); if (SelectCount) DeleteSelected(19); HideEditCaret(); { LPREPLIST lpRep = &RepList; while (Length > (LONG)sizeof(lpRep->Buf)) { InsertBuffer((LPBYTE)lpRep->Buf, sizeof(lpRep->Buf), 2); Length -= sizeof(lpRep->Buf); if ((lpRep = lpRep->Next) == NULL) break; } if (Length && lpRep != NULL) InsertBuffer((LPBYTE)lpRep->Buf, Length, 2); FreeRepList(); } GoBackAndChar(&CurrPos); Mode = SaveMode; FindValidPosition(&CurrPos, (WORD)(Mode==InsertMode)); SendMessage(hDlg, DM_SETDEFID, IDOK, 0); SetFocus(GetDlgItem(hDlg, IDOK)); EnableWindow(GetDlgItem(hDlg, IDC_REPLACE), FALSE); }
// maps:remove/2 [20] term_t cbif_remove2(proc_t *proc, term_t *regs) { term_t Key = regs[0]; term_t Map = regs[1]; if (!is_boxed_map(Map)) badarg(Map); t_map_t *m = (t_map_t *)peel_boxed(Map); int index = map_key_index(Key, m->keys); if (index < 0) return Map; uint32_t *p = peel_tuple(m->keys); int size = *p++; term_t *ks = p; int needed = 1 +size-1 +WSIZE(t_map_t) +size-1; uint32_t *htop = heap_alloc(&proc->hp, needed); term_t keys = tag_tuple(htop); *htop++ = size-1; memcpy(htop, ks, index *sizeof(term_t)); htop += index; memcpy(htop, ks +index +1, (size -index -1) *sizeof(term_t)); htop += (size -index -1); term_t out = tag_boxed(htop); t_map_t *m1 = (t_map_t *)htop; box_map(htop, size-1, keys); heap_set_top(&proc->hp, htop); memcpy(m1->values, m->values, index *sizeof(term_t)); memcpy(m1->values +index +1, m->values +index +1, (size -index -1) *sizeof(term_t)); return out; }
void RecalcStatusRow(void) { /*called initially and if main window (and status row) changes width*/ INT Right = ClientRect.right; if (WinVersion < MAKEWORD(95,3) || !SizeGrip) Right -= XFIELD_OFFSET; else Right -= XFIELD_OFFSET - 2; if (Right > 0) { INT i, w = 0; WCHAR b[12]; extern WCHAR StatusLineFormat[8], StatusColFormat[8]; if (SizeGrip) Right -= 15; StatusFields[0].Width = StatusWidth(L"nnnnnnnnnnnnnnnnnnnn"); StatusFields[1].Width = StatusWidth(L"Aguantado"); StatusFields[2].Width = StatusWidth(CapsLock); StatusFields[3].Width = StatusWidth(NumLock); StatusFields[4].Width = StatusWidth(L"--100%--"); _snwprintf(b, WSIZE(b), StatusLineFormat, 0L); StatusFields[5].Width = StatusWidth(b); _snwprintf(b, WSIZE(b), StatusColFormat, 0L); StatusFields[6].Width = StatusWidth(b); StatusFields[1].Centered = StatusFields[4].Centered = TRUE; for (i=0; StatusFields[i].Width; ++i) w += StatusFields[i].Width + 6; if (w > ClientRect.right) { w -= StatusFields[2].Width + 6; w -= StatusFields[3].Width + 6; StatusFields[2].Width = StatusFields[3].Width = 0; } if (w > ClientRect.right) { w -= StatusFields[4].Width + 6; StatusFields[4].Width = 0; } if (w > ClientRect.right) { w -= StatusFields[5].Width + 6; w -= StatusFields[6].Width + 6; StatusFields[5].Width = StatusFields[6].Width = 0; } if (w > ClientRect.right) { /*w -= StatusFields[1].Width + 6;*/ StatusFields[1].Width = 0; } w = Right; for (i=6; i>=0; --i) { INT w2; w2 = StatusFields[i].Width; StatusFields[i].x = w - w2; if (w2) { w -= w2 + 4; if (i==4 || i==2) w -= 5; } } StatusFields[0].Width += StatusFields[0].x; StatusFields[0].x = 0; if (WinVersion < MAKEWORD(95,3) || !SizeGrip) { StatusFields[0].Width -= XFIELD_OFFSET; StatusFields[0].x += XFIELD_OFFSET; } StatusTextHeight = StatusHeight - (WinVersion>=MAKEWORD(95,3) && SizeGrip ? 6 : 8); if (StatusFields[4].Text) return; StatusFields[2].Text = GetKeyState(VK_CAPITAL)&1 ? CapsLock : (PWSTR)0; StatusFields[3].Text = GetKeyState(VK_NUMLOCK)&1 ? NumLock : (PWSTR)0; StatusFields[4].Text = L"--100%--"; StatusFields[5].Text = L"00001"; StatusFields[6].Text = L"001"; } }
void NewCapsString(VOID) { LOADSTRINGW(hInst, 903, CapsLock, WSIZE(CapsLock)); RecalcStatusRow(); AdjustWindowParts(ClientRect.bottom, ClientRect.bottom); }
BOOL CALLBACK SearchCallback(HWND hDlg, UINT uMsg, WPARAM wPar, LPARAM lPar) { extern BOOL SearchBoxPosition, HexEditTextSide; extern INT SearchBoxX, SearchBoxY; static RECT DlgRect; static BOOL Enabled; static CHAR CloseString[10]; PARAM_NOT_USED(lPar); switch (uMsg) { RECT r; case WM_INITDIALOG: GetWindowRect(hDlg, &DlgRect); GetWindowRect(GetDlgItem(hDlg, IDC_REPLACE), &r); SetWindowPos(hDlg, 0, SearchBoxX, SearchBoxY, DlgRect.right - DlgRect.left, r.top - DlgRect.top, SearchBoxPosition ? SWP_NOZORDER : SWP_NOZORDER | SWP_NOMOVE); SendMessage(hDlg, DM_REPOSITION, 0, 0); EnableWindow(GetDlgItem(hDlg, IDC_SHOWREPLACE), FALSE); if (HexInput != (HexEditMode && !HexEditTextSide)) { HexInput ^= TRUE; *SearchBuf = '\0'; } if (SelectCount && (HexInput ? 3 : 1) * SelectCount < WSIZE(SearchBuf)) { POSITION SelPos; INT i, c; PWSTR p = SearchBuf; SelPos = SelectStart; for (i=(INT)SelectCount; i; --i) { if (HexInput) { c = ByteAt(&SelPos); if (Advance(&SelPos, 1) != 1) break; if (UtfEncoding == 16 && i > 1) { if (UtfLsbFirst) c |= ByteAt(&SelPos) << 8; else c = (c << 8) | ByteAt(&SelPos); if (Advance(&SelPos, 1) != 1) break; --i; } p += _snwprintf(p, WSIZE(SearchBuf) - (p-SearchBuf), UtfEncoding == 16 ? L"%04x " : L"%02x ", c); } else { if ((c = CharAt(&SelPos)) == C_CRLF) c = '\r'; else if (!UtfEncoding) c = CharSetToUnicode(c); if (UtfEncoding == 16) { if (i > 1) --i; if (Advance(&SelPos, 2) != 2) break; } else if (Advance(&SelPos, 1) != 1) break; *p++ = c; } } if (HexInput) --p; *p = '\0'; if (*SearchBuf && !ViewOnlyFlag) EnableWindow(GetDlgItem(hDlg, IDC_SHOWREPLACE), TRUE); } else { PWSTR p; if ((p = ExtractIdentifier(NULL)) != NULL) wcsncpy(SearchBuf, p, WSIZE(SearchBuf)); } Enabled = *SearchBuf!='\0'; if (Enabled) { EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); SetDlgItemTextW(hDlg, IDC_SEARCHSTRING, SearchBuf); SendMessage(hDlg, DM_SETDEFID, IDOK, 0L); } else { SendMessage(hDlg, DM_SETDEFID, IDCANCEL, 0L); EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); } EnableWindow(GetDlgItem(hDlg, IDC_REPLACESTRING), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_REPLACE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_REPLACEALL), FALSE); CheckDlgButton(hDlg, *SrchDispBuf=='?' ? IDC_BACKWARD : IDC_FORWARD, TRUE); CheckDlgButton(hDlg, IDC_MATCHCASE, !IgnoreCaseFlag); CheckDlgButton(hDlg, IDC_MAGIC, Magic); CheckDlgButton(hDlg, IDC_HEXSEARCH, HexInput); CheckDlgButton(hDlg, IDC_WHOLEWORD, WholeWord); CheckDlgButton(hDlg, IDC_WRAPSCAN, WrapScanFlag); LOADSTRING(hInst, 909, CloseString, sizeof(CloseString)); ReplaceOpen = FALSE; PostMessage(hDlg, WM_COMMAND, 4569, 0); /*for Wine*/ return (TRUE); case WM_COMMAND: switch (COMMAND) { case 4569: /*Disable/enable again for Wine...*/ EnableWindow(GetDlgItem(hDlg, IDOK), Enabled); break; case IDOK: SearchOk(hDlg); break; case IDCANCEL: if (ReplacingAll) Interrupted = TRUE; PostMessage(hDlg, WM_CLOSE, 0, 0); break; case IDC_SEARCHSTRING: GetDlgItemTextW(hDlg, IDC_SEARCHSTRING, CommandBuf, 4); if (Enabled != (*CommandBuf != '\0')) { if (Enabled ^= TRUE) { EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); SendMessage(hDlg, DM_SETDEFID, IDOK, 0L); } else { SendMessage(hDlg, DM_SETDEFID, IDCANCEL, 0L); EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); } if (ReplaceOpen) { EnableWindow(GetDlgItem(hDlg,IDC_REPLACE), Enabled); EnableWindow(GetDlgItem(hDlg,IDC_REPLACEALL),Enabled); } } break; case IDC_SHOWREPLACE: EnableWindow(GetDlgItem(hDlg, IDC_REPLACESTRING), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_REPLACE), SelectCount!=0); EnableWindow(GetDlgItem(hDlg, IDC_REPLACEALL), TRUE); SetWindowPos(hDlg, 0,0,0, DlgRect.right-DlgRect.left, DlgRect.bottom-DlgRect.top, SWP_NOZORDER | SWP_NOMOVE); SendMessage(hDlg, DM_REPOSITION, 0, 0); SetFocus(GetDlgItem(hDlg, IDC_REPLACESTRING)); SendMessage(hDlg, DM_SETDEFID, IDC_REPLACE, 0L); EnableWindow(GetDlgItem(hDlg, IDC_SHOWREPLACE), FALSE); ReplaceOpen = TRUE; break; case IDC_REPLACE: ReplaceSearched(hDlg); SetDlgItemText(hDlg, IDCANCEL, CloseString); break; case IDC_REPLACEALL: SetupSearchString(hDlg, NULL); GlobalSubst(hDlg); SetDlgItemText(hDlg, IDCANCEL, CloseString); } return (TRUE); case WM_MOVE: case WM_CLOSE: SearchBoxPosition = TRUE; GetWindowRect(hDlg, &r); SearchBoxX = r.left; SearchBoxY = r.top; if (uMsg == WM_CLOSE) { DestroyWindow(hDlg); hwndSearch = NULL; } return (TRUE); } return (FALSE); }
void GlobalSubst(HWND hDlg) { PWSTR p = CommandBuf; INT n; Magic = IsDlgButtonChecked(hDlg, IDC_MAGIC); HexInput = IsDlgButtonChecked(hDlg, IDC_HEXSEARCH); ReplacingAll = TRUE; p += n = _snwprintf(p, WSIZE(CommandBuf), L":%%s//"); n += GetDlgItemTextW(hDlg, IDC_REPLACESTRING, p, WSIZE(CommandBuf) - n); while (*p) { switch (*p) { case '\\': if (Magic) { if (*++p >= '0' && *p <= '7') { if (*p >= '0' && *p <= '3') ++p; if (*p >= '0' && *p <= '7') ++p; if (*p >= '0' && *p <= '7') ++p; continue; } if (*p == '%') { if (ISHEX(p[1])) ++p; if (ISHEX(p[1])) ++p; } break; } /*FALLTHROUGH*/ case '&': if (*p=='&' && !Magic!=MagicFlag) break; /*FALLTHROUGH*/ case '/': if (n+1 < WSIZE(CommandBuf)) { memmove(p+1, p, 2*wcslen(p)+2); *p++ = '\\'; ++n; } break; default: if (HexInput) { if (!ISHEX(*p)) { if (*p != ' ') { hwndErrorParent = hDlg; ErrorBox(MB_ICONSTOP, 239); hwndErrorParent = hwndMain; return; } memmove(p, p+1, 2*wcslen(p)); --n; continue; } if (n+2 < WSIZE(CommandBuf)) { memmove(p+2, p, 2*wcslen(p)+2); *p++ = '\\'; *p++ = '%'; if (ISHEX(p[1])) ++p; n += 2; } } } ++p; } if (n+2 < WSIZE(CommandBuf)) wcscpy(p, L"/g"); SendMessage(hDlg, DM_SETDEFID, IDCANCEL, 0); SetFocus(GetDlgItem(hDlg, IDCANCEL)); EnableControls(hDlg, FALSE); CommandExec(CommandBuf); EnableControls(hDlg, TRUE); ReplacingAll = FALSE; }
PWSTR SetupSearchString(HWND hDlg, INT *Error) { PWSTR pS = SearchBuf, pD = CommandBuf; BOOL Ok = TRUE, OpenBracket = FALSE; Magic = IsDlgButtonChecked(hDlg, IDC_MAGIC); HexInput = IsDlgButtonChecked(hDlg, IDC_HEXSEARCH); WholeWord = IsDlgButtonChecked(hDlg, IDC_WHOLEWORD); IgnoreCaseFlag = IsDlgButtonChecked(hDlg, IDC_MATCHCASE) == FALSE; WrapScanFlag = IsDlgButtonChecked(hDlg, IDC_WRAPSCAN); *CommandBuf = IsDlgButtonChecked(hDlg, IDC_FORWARD) ? '/' : '?'; GetDlgItemTextW(hDlg, IDC_SEARCHSTRING, SearchBuf, WSIZE(SearchBuf)); if (WholeWord) { *++pD = '\\'; *++pD = '<'; } for (;;) { switch (*++pD = *pS++) { case '\\': if (Magic) { switch (*pS) { case '\0': break; case '%': *++pD = *pS++; if (!ISHEX(*pS)) break; *++pD = *pS++; if (ISHEX(*pS)) *++pD = *pS++; continue; case '0': case '1': case '2': case '3': *++pD = *pS++; if (*pS >= '0' && *pS <= '7') *++pD = *pS++; if (*pS >= '0' && *pS <= '7') *++pD = *pS++; continue; default: *++pD = *pS++; continue; } } if (HexInput) Ok = FALSE; break; case '/': case '?': if (HexInput) { Ok = FALSE; break; } if (*pD != *CommandBuf) continue; /*FALLTHROUGH*/ case '\0': break; case '[': OpenBracket = TRUE; /*FALLTHROUGH*/ case '*': case '.': if (HexInput && !Magic) { Ok = FALSE; break; } if (!MagicFlag != !Magic) break; continue; case '^': case '$': if (!Magic) { if (HexInput) Ok = FALSE; break; } continue; case '-': case ']': if (Magic && OpenBracket) { if (!(OpenBracket = *pD != ']') && !MagicFlag) break; continue; } /*FALLTHROUGH*/ default: if (HexInput) { if (ISHEX(*pD)) { pD[2] = *pD; *pD++ = '\\'; *pD++ = '%'; if (ISHEX(*pS)) *++pD = *pS++; if (UtfEncoding == 16 && ISHEX(pS[0]) && ISHEX(pS[1])) { *++pD = *pS++; *++pD = *pS++; } } else if (*pD-- != ' ') { Ok = FALSE; break; } } continue; } if (!Ok) { if (Error != NULL) *Error = 239; return (NULL); } if (*pD == '\0') break; pD[1] = *pD; *pD++ = '\\'; } if (WholeWord) wcscpy(pD, L"\\>"); return BuildMatchList(CommandBuf, *CommandBuf, Error); }
// maps:from_list/1 [26] term_t cbif_from_list1(proc_t *proc, term_t *regs) { term_t List = regs[0]; if (!is_list(List)) badarg(List); int len = list_len(List); term_t ks[len]; //XXX: imminent stack overflow term_t vs[len]; int n = 0; term_t l = List; while (is_cons(l)) { term_t *cons = peel_cons(l); if (!is_tuple(cons[0])) badarg(List); uint32_t *p = peel_tuple(cons[0]); if (*p++ != 2) badarg(List); term_t k = *p++; term_t v = *p++; if (n == 0 || is_term_smaller(k, ks[0])) { memmove(ks +1, ks, n *sizeof(term_t)); memmove(vs +1, vs, n *sizeof(term_t)); ks[0] = k; vs[0] = v; n++; } else { term_t *alpha = ks; term_t *beta = ks +n; // *alpha =< k while (beta > alpha+1) { term_t *mid = alpha + (beta -alpha +1)/2; if (is_term_smaller(k, *mid)) beta = mid; else alpha = mid; } assert(beta == alpha+1); int index = alpha -ks; if (k == *alpha || are_terms_equal(k, *alpha, 1)) vs[index] = v; else { index++; // ks[index] > k now memmove(ks +index +1, ks +index, (n -index) *sizeof(term_t)); memmove(vs +index +1, vs +index, (n -index) *sizeof(term_t)); ks[index] = k; vs[index] = v; n++; } } l = cons[1]; } if (!is_nil(l)) badarg(List); int needed = 1 +n + WSIZE(t_map_t) +n; uint32_t *htop = heap_alloc(&proc->hp, needed); term_t keys = tag_tuple(htop); *htop++ = n; memcpy(htop, ks, n *sizeof(term_t)); htop += n; term_t out = tag_boxed(htop); term_t *values = htop +WSIZE(t_map_t); box_map(htop, n, keys); heap_set_top(&proc->hp, htop); memcpy(values, vs, n *sizeof(term_t)); return out; }
// maps:merge/2 [23] term_t cbif_merge2(proc_t *proc, term_t *regs) { term_t Map1 = regs[0]; term_t Map2 = regs[1]; if (!is_boxed_map(Map1)) badarg(Map1); if (!is_boxed_map(Map2)) badarg(Map2); t_map_t *m1 = (t_map_t *)peel_boxed(Map1); uint32_t *p1 = peel_tuple(m1->keys); int size1 = *p1++; term_t *ks1 = p1; term_t *vs1 = m1->values; t_map_t *m2 = (t_map_t *)peel_boxed(Map2); uint32_t *p2 = peel_tuple(m2->keys); int size2 = *p2++; term_t *ks2 = p2; term_t *vs2 = m2->values; term_t mks[size1+size2]; //XXX: stack overflow term_t mvs[size1+size2]; term_t *ks3 = mks; term_t *vs3 = mvs; int ss1 = size1; int ss2 = size2; int size = 0; while (size1 > 0 && size2 > 0) { term_t a = *ks1; term_t b = *ks2; if (is_term_smaller(a, b)) { *ks3++ = *ks1++; *vs3++ = *vs1++; size1--; } else if (a == b || are_terms_equal(a, b, 1)) { ks1++; vs1++; size1--; *ks3++ = *ks2++; *vs3++ = *vs2++; size2--; } else { *ks3++ = *ks2++; *vs3++ = *vs2++; size2--; } size++; } while (size1-- > 0) { *ks3++ = *ks1++; *vs3++ = *vs1++; size++; } while (size2-- > 0) { *ks3++ = *ks2++; *vs3++ = *vs2++; size++; } if (size == ss1 || size == ss2) { // reuse keys term_t keys = (size == ss1) ?m1->keys :m2->keys; int needed = WSIZE(t_map_t) +size; uint32_t *p = heap_alloc(&proc->hp, needed); term_t out = tag_boxed(p); term_t *values = p +WSIZE(t_map_t); box_map(p, size, keys); heap_set_top(&proc->hp, p); memcpy(values, mvs, size *sizeof(term_t)); return out; } else { // new keys int needed = 1 +size +WSIZE(t_map_t) +size; uint32_t *p = heap_alloc(&proc->hp, needed); term_t keys = tag_tuple(p); *p++ = size; memcpy(p, mks, size *sizeof(term_t)); term_t out = tag_boxed(p); term_t *values = p +WSIZE(t_map_t); box_map(p, size, keys); heap_set_top(&proc->hp, p); memcpy(values, mvs, size *sizeof(term_t)); return out; } }
static uint32_t *terms_copy(stack_t *stack, term_t *terms, int num, uint32_t *htop, t_proc_bin_t **pbs) { next_term: if (num == 0) { if (stack_is_empty(stack)) return htop; ets_deferred_copy_t *pop = (ets_deferred_copy_t *)stack_pop(stack); terms = pop->terms; num = pop->num; goto next_term; } term_t t = terms[0]; if (is_immed(t)) { terms++; num--; goto next_term; } term_t copy = noval; if (is_cons(t)) { term_t *cons = peel_cons(t); copy = tag_cons(htop); term_t *new_cons = htop; do { new_cons[0] = cons[0]; new_cons[1] = cons[1]; htop += 2; if (!is_immed(new_cons[0])) DEFER_COPY(stack, new_cons, 1); term_t tail = new_cons[1]; if (is_immed(tail)) break; if (!is_cons(tail)) { DEFER_COPY(stack, new_cons +1, 1); break; } new_cons[1] = tag_cons(htop); cons = peel_cons(tail); new_cons = htop; } while (1); } else if (is_tuple(t)) { uint32_t *p = peel_tuple(t); int arity = *p++; if (arity == 0) copy = ZERO_TUPLE; else { copy = tag_tuple(htop); *htop++ = arity; memcpy(htop, p, arity *sizeof(term_t)); DEFER_COPY(stack, htop, arity); htop += arity; } } else { assert(is_boxed(t)); uint32_t *tdata = peel_boxed(t); copy = tag_boxed(htop); switch (boxed_tag(tdata)) { case SUBTAG_POS_BIGNUM: case SUBTAG_NEG_BIGNUM: { bignum_t *bn = (bignum_t *)tdata; int wsize = WSIZE(bignum_t) + (bn->used*sizeof(uint16_t) +3) /4; memcpy(htop, tdata, wsize *sizeof(uint32_t)); htop += wsize; break; } case SUBTAG_FLOAT: EASY_COPY(t_float_t); break; case SUBTAG_FUN: { t_fun_t *new_fun = (t_fun_t *)htop; int num_free = fun_num_free(tdata); int wsize = WSIZE(t_fun_t) + num_free; memcpy(new_fun, tdata, wsize *sizeof(uint32_t)); DEFER_COPY(stack, new_fun->frozen, num_free); htop += wsize; break; } case SUBTAG_EXPORT: EASY_COPY(t_export_t); break; case SUBTAG_PID: EASY_COPY(t_long_pid_t); break; case SUBTAG_OID: EASY_COPY(t_long_oid_t); break; case SUBTAG_REF: EASY_COPY(t_long_ref_t); break; case SUBTAG_PROC_BIN: { t_proc_bin_t *pb = (t_proc_bin_t *)htop; memcpy(htop, tdata, sizeof(t_proc_bin_t)); // 1+ bin node refc proc_bin_link(pbs, pb, 0); htop += WSIZE(t_proc_bin_t); break; } case SUBTAG_HEAP_BIN: { t_heap_bin_t *hb = (t_heap_bin_t *)tdata; int wsize = WSIZE(t_heap_bin_t) + (hb->byte_size +3) /4; memcpy(htop, tdata, wsize*sizeof(uint32_t)); htop += wsize; break; } case SUBTAG_MATCH_CTX: { t_match_ctx_t *new_mc = (t_match_ctx_t *)htop; memcpy(new_mc, tdata, sizeof(t_match_ctx_t)); DEFER_COPY(stack, &new_mc->parent, 1); htop += WSIZE(t_match_ctx_t); break; } default: // SUBTAG_SUB_BIN { assert(boxed_tag(tdata) == SUBTAG_SUB_BIN); t_sub_bin_t *new_sb = (t_sub_bin_t *)htop; memcpy(new_sb, tdata, sizeof(t_sub_bin_t)); DEFER_COPY(stack, &new_sb->parent, 1); htop += WSIZE(t_sub_bin_t); break; } } } assert(copy != noval); *terms++ = copy; num--; goto next_term; }
static int ets_terms_copy_size2(stack_t *st) { int hsize = 0; pop_term: if (stack_is_empty(st)) return hsize; term_t t = (term_t)*stack_pop(st); tail_recur: if (is_immed(t)) goto pop_term; if (is_cons(t)) { while (is_cons(t)) { hsize += 2; term_t *cons = peel_cons(t); uint32_t *push = stack_push_N(st); if (push == 0) return -NO_MEMORY; *push = cons[0]; t = cons[1]; } if (t != nil) goto tail_recur; goto pop_term; } if (is_tuple(t)) { uint32_t *p = peel_tuple(t); int arity = *p++; if (arity == 0) goto pop_term; // no heap frag hsize += 1 +arity; for (int i = 0; i < arity -1; i++) { uint32_t *push = stack_push_N(st); if (push == 0) return -NO_MEMORY; *push = p[i]; } t = p[arity -1]; goto tail_recur; } assert(is_boxed(t)); uint32_t *tdata = peel_boxed(t); switch (boxed_tag(tdata)) { case SUBTAG_POS_BIGNUM: case SUBTAG_NEG_BIGNUM: { bignum_t *bn = (bignum_t *)tdata; hsize += WSIZE(bignum_t) + (bn->used*sizeof(uint16_t) +3) /4; goto pop_term; } case SUBTAG_FLOAT: hsize += WSIZE(t_float_t); goto pop_term; case SUBTAG_FUN: { t_fun_t *fun = (t_fun_t *)tdata; int num_free = fun_num_free(tdata); hsize += WSIZE(t_fun_t) + num_free; for (int i = 0; i < num_free -1; i++) { uint32_t *push = stack_push_N(st); if (push == 0) return -NO_MEMORY; *push = fun->frozen[i]; } if (num_free == 0) goto pop_term; t = fun->frozen[num_free -1]; goto tail_recur; } case SUBTAG_EXPORT: hsize += WSIZE(t_export_t); goto pop_term; case SUBTAG_PID: hsize += WSIZE(t_long_pid_t); goto pop_term; case SUBTAG_OID: hsize += WSIZE(t_long_oid_t); goto pop_term; case SUBTAG_REF: hsize += WSIZE(t_long_ref_t); goto pop_term; case SUBTAG_PROC_BIN: hsize += WSIZE(t_proc_bin_t); goto pop_term; case SUBTAG_HEAP_BIN: { t_heap_bin_t *hb = (t_heap_bin_t *)tdata; hsize += WSIZE(t_heap_bin_t) + (hb->byte_size +3) /4; goto pop_term; } case SUBTAG_MATCH_CTX: { t_match_ctx_t *mc = (t_match_ctx_t *)tdata; int num_slots = match_ctx_num_slots(tdata); hsize += WSIZE(t_match_ctx_t) + num_slots*sizeof(int64_t) /4; t = mc->parent; goto tail_recur; } default: // SUBTAG_SUB_BIN { assert(boxed_tag(tdata) == SUBTAG_SUB_BIN); t_sub_bin_t *sb = (t_sub_bin_t *)tdata; hsize += WSIZE(t_sub_bin_t); t = sb->parent; goto tail_recur; } } }