Пример #1
0
// 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;
	}
}
Пример #2
0
// 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);
}
Пример #3
0
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
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
// 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;	
}
Пример #7
0
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";
	}
}
Пример #8
0
void NewCapsString(VOID) {

	LOADSTRINGW(hInst, 903, CapsLock, WSIZE(CapsLock));
	RecalcStatusRow();
	AdjustWindowParts(ClientRect.bottom, ClientRect.bottom);
}
Пример #9
0
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);
}
Пример #10
0
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;
}
Пример #11
0
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);
}
Пример #12
0
// 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;	
}
Пример #13
0
// 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;
	}
}
Пример #14
0
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;
}
Пример #15
0
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;
	}
	}
}