Go Back

How Do I Write Bitness Agnostic ^VAL Code?

Keywords: ^VAL, return value
Topics: 64bit, 32bit

Consider the following toy program:
 

main

	record workVars
		kernel32Handle, D_ADDR
		processHeap, i8
	endrecord

proc

	kernel32Handle = %dll_open( "Kernel32" )
	processHeap = GetProcessHeap(kernel32Handle)
	xcall dll_close(kernel32Handle)
	nop

endmain

function GetProcessHeap ,^val
	kernel32Handle, D_ADDR
	endparams
proc
	freturn %dll_call(kernel32Handle, DLL_TYPE_WINAPI, "GetProcessHeap")
end

This particular function works in both 64bit and 32bit Synergy. However in 32bit Synergy it is wasteful that processHeap is defined as an i8.

^VAL functions (https://www.synergex.com/docs/versions/v111/index.htm#lrm/lrmChap7Writingsubroutinesandfunctions.htm#%5EVAL%20functions) are defined as returning "...an integer value that is the natural integer size of the machine. That is, for a 32-bit machine, it returns an i4; for a 64-bit machine, it returns an i8."

We are looking for something similar to D_ADDR for ^VAL functions to allow us to write bit-agnostic code.

5 Answers
0   | Posted by Ace Olszowka to Synergy DBL on 11/21/2019 10:23 PM
Mark Vinten
You may call it wasteful, but in memory terms these days, it's not going to eat a lot up unless you are holding onto those values in a large array for an extended period of time.  Also, if you happen to be returning a handle to things or the size of things on a 64-bit machine, you may well need the i8 anyway.

At the end of the day, D_ADDR is defined as being aligned to the bitness of the machin, so, IMHO, the ^VAL is agnositic unless you want to be specific and return an I4.

 

11/22/2019 8:24 AM   0  
Ace Olszowka

@Mark Vinten
> unless you are holding onto those values in a large array for an extended period of time.

*grin*

"If a feature was available to us, it was used and abused, in all sorts of unique and interesting ways" - Ace Olszowka Synergex DevPartner 2018 "Computers Unlimited's Journey to Continuous Integration"

Also consider storage into long lived structures, inserted into a repository, or even better into a database.

> At the end of the day, D_ADDR is defined as being aligned to the bitness of the machin, so, IMHO, the ^VAL is agnositic unless you want to be specific and return an I4.

We need an equivalent of D_ADDR to serve as the return type for ^VAL functions.

In the above example D_ADDR could be (ab)used to serve as the return value of ^VAL functions but that would not be inline with how it is documented to behave.


11/22/2019 3:00 PM   0  
Phillip Bratt
The purpose of ^VAL wasn’t to be used for bit agnostic code. ^VAL is a high-performance calling convention that returns (or passes) a value in a CPU register. CPU registers being 32-bit or 64-bit, based on the architecture. It wasn’t designed with portability in mind (32-bit vs 64-bit) but for speed. Similar to INT_PTR in .NET. Which means, in most cases, that the values returned are intended to be smaller than 32-bit int.

There is a newly created tracker, for release in the next developer build after 11.1.1a, which adds a -W4 truncation warning to inform when a function/routine, whose return type is ^VAL, could potentially truncate the value to a d2/d4/i1/i2/i4 variable. However, this warning will also appear on lines where the developer correctly used ^VAL as intended and the implicit truncation was expected. An (int) cast or (d) cast can be added in the code to remove this warning for those valid cases. There are similar truncation warnings that can be enabled in C++ compilers e.g. the int=strlen(string) returning a 64-bit size_t on 64-bit platforms. We do turn them on to find outliers on occasion and then disable them again. Like those warnings in C++, this warning should help identify areas in code where truncation is happening. You can then identify if it is a valid case of truncation and add a cast (int) or (d) or fix the code. This should help resolve the problem you are trying to fix.

 

11/26/2019 5:16 PM   0  
Ace Olszowka
@Phillip Bratt

To try and follow up on this; in .NET we'd use INTPTR as you mentioned; when using ^VAL what are we supposed to use? D_ADDR does not seem like the correct structure to use.

12/3/2019 3:30 PM   0  
Ace Olszowka
See https://synergexresourcecenter.force.com/siteidea?id=0870d000000Tfx4AAC

12/18/2019 2:23 PM   0  
Please log in to comment or answer this question.