ACS dynamic parameter strings
Moderator: GZDoom Developers
-
-
- Posts: 3108
- Joined: Wed Nov 24, 2004 12:59 pm
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ACS dynamic parameter strings
Probably a better return value would be the number of characters copied, but even then it would only apply to map arrays. It would be basically impossible for it to fail on world/global arrays unless you rig it through hex editing.
And technically the instructions I propose would take the offset in the destination as the 2nd argument. It's just hidden in the same why it is when printing character arrays.
And technically the instructions I propose would take the offset in the destination as the 2nd argument. It's just hidden in the same why it is when printing character arrays.
-
- Posts: 1097
- Joined: Tue Nov 03, 2009 9:19 am
Re: ACS dynamic parameter strings
I don't want to hide the offset to the end-user, though. And while there is no legal way to fail on global and world arrays, the fact remains that there is a legal way to fail; unless we prohibit the use of map-arrays.
But we can make that a difference in the underlying code flow:
Save to global array: No data to stack.
Save to world array: No data to stack.
Save to map array: Success/failure to stack.
Now, in a named function presented to the user, we introduce the following difference:
When a user makes a void call to strcpy:
* Drop result value for map array
* Use minimal number of instructions for other arrays
When a user makes an evaluation call to strcpy
* Use minimal number of instructions for map array (results in success/failure being pushed to stack)
* Push success to stack for other arrays
When ACC++ uses strcpy for internal purposes:
These are just three new instructions; use information to copy data to...
* map array, with result to stack
* world array with no result
* global array with no result
As long as you work with only global array, you can use the underlying feature without any return value.
If you add support for map-arrays, you can drop the result value or tack on an implicit conditional branch for failure. If you're taking steps to guarantee or predetermine success, the return value might be worthless to you.
... I'd like to return number of characters copied, but an empty string would succeed with 0, which is mildly ambigous. The above scheme would also be much harder to implement if the return value is bound to provide more than a boolean outcome.
But we can make that a difference in the underlying code flow:
Save to global array: No data to stack.
Save to world array: No data to stack.
Save to map array: Success/failure to stack.
Now, in a named function presented to the user, we introduce the following difference:
When a user makes a void call to strcpy:
* Drop result value for map array
* Use minimal number of instructions for other arrays
When a user makes an evaluation call to strcpy
* Use minimal number of instructions for map array (results in success/failure being pushed to stack)
* Push success to stack for other arrays
When ACC++ uses strcpy for internal purposes:
These are just three new instructions; use information to copy data to...
* map array, with result to stack
* world array with no result
* global array with no result
As long as you work with only global array, you can use the underlying feature without any return value.
If you add support for map-arrays, you can drop the result value or tack on an implicit conditional branch for failure. If you're taking steps to guarantee or predetermine success, the return value might be worthless to you.
... I'd like to return number of characters copied, but an empty string would succeed with 0, which is mildly ambigous. The above scheme would also be much harder to implement if the return value is bound to provide more than a boolean outcome.
-
- Posts: 1749
- Joined: Mon Aug 11, 2008 12:59 pm
- Graphics Processor: nVidia with Vulkan support
- Location: Winchester, VA
Re: ACS dynamic parameter strings
Added strparam to the wiki, please correct if I fucked it up.
-
-
- Posts: 3108
- Joined: Wed Nov 24, 2004 12:59 pm
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ACS dynamic parameter strings
While it shouldn't be a problem for ACC++, I don't think have a different return value for different array types is a particularly good idea. One thing to consider is with map arrays it's possible to determine a failure ahead of time. Honestly you could just define what will happen in the case of invalid input. If the array is too short it only copies until it reaches the end of the array. If the offsets are invalid (source or destination) it does nothing.FDARI wrote:Save to global array: No data to stack.
Save to world array: No data to stack.
Save to map array: Success/failure to stack.
Both of these conditions can be checked by other means: if(strlen(source) > ARRAYSIZE-offset) and if(destoffset > ARRAYSIZE || destoffset < 0)
-
- Posts: 1097
- Joined: Tue Nov 03, 2009 9:19 am
Re: ACS dynamic parameter strings
With dynamic ACS parameter strings, and with string libraries, you cannot know at compile time how long the string will be. Without that knowledge, you cannot verify the outcome before runtime.
When I read your response I'm not entirely sure if we discuss the same thing.
Internally, save to global/world/map array is three different calls. One of them would put a return value on stack.
ACC.EXE would expose to the modder a single function with one behaviour, consistent across all three array types.
Only map-arrays would ever cause a failure-result (unless there is a limit to global array length afterall).
Do you find it problematic that there would be similar pcodes in zdoom with different characteristics? For what reason; because it makes ACC-code unclear? The Pcodes for global and world variables could have _VOID tacked on, to imply that there is no return value, and making it apparent in ACC-code that a result must be appended by the compiler.
We could also omit all map-array support to achieve a uniform definition.
When I read your response I'm not entirely sure if we discuss the same thing.
Internally, save to global/world/map array is three different calls. One of them would put a return value on stack.
ACC.EXE would expose to the modder a single function with one behaviour, consistent across all three array types.
Only map-arrays would ever cause a failure-result (unless there is a limit to global array length afterall).
Do you find it problematic that there would be similar pcodes in zdoom with different characteristics? For what reason; because it makes ACC-code unclear? The Pcodes for global and world variables could have _VOID tacked on, to imply that there is no return value, and making it apparent in ACC-code that a result must be appended by the compiler.
We could also omit all map-array support to achieve a uniform definition.
-
- Lead GZDoom+Raze Developer
- Posts: 48597
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ACS dynamic parameter strings
What you are proposing sounds like nonsense. If one function compiles to 3 pcodes all need to have the same return semantics, even if for 2 of them it's practically useless.
-
-
- Posts: 3108
- Joined: Wed Nov 24, 2004 12:59 pm
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ACS dynamic parameter strings
Sure you can since strlen is a function, so yes you can tell if the function is going to "fail" before hand.FDARI wrote:With dynamic ACS parameter strings, and with string libraries, you cannot know at compile time how long the string will be. Without that knowledge, you cannot verify the outcome before runtime.
-
- Posts: 1097
- Joined: Tue Nov 03, 2009 9:19 am
Re: ACS dynamic parameter strings
While it may not be the best approach, it is not nonsense. I am suggesting that the compiler should take three slightly different functions, and present them through a common interface.
To satisfy the interface "int strcpy(array,...)" (return type is the debated element here) it would need a result at the end of all code paths. However, it is not technically necessary for that return value to be the product of one of the strcpy-pcodes.
Call as statement:
Map array: FUNCTION (return int) + DROP
World array, global array: FUNCTION (no return)
Call as expression:
Map array: FUNCTION (return int)
World array, global array: FUNCTION (no return) + PUSH 1
Blzut3: The user can manually call strlen to verify that the call should not fail based on string length, that is true. I thought you meant that the compiler could.
To satisfy the interface "int strcpy(array,...)" (return type is the debated element here) it would need a result at the end of all code paths. However, it is not technically necessary for that return value to be the product of one of the strcpy-pcodes.
Call as statement:
Map array: FUNCTION (return int) + DROP
World array, global array: FUNCTION (no return)
Call as expression:
Map array: FUNCTION (return int)
World array, global array: FUNCTION (no return) + PUSH 1
Blzut3: The user can manually call strlen to verify that the call should not fail based on string length, that is true. I thought you meant that the compiler could.
-
-
- Posts: 3108
- Joined: Wed Nov 24, 2004 12:59 pm
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ACS dynamic parameter strings
No, and the compiler can't tell even if you have a return value. My point is doing it manually gives the same result as having a return value. In addition doing it manually works for ACS++ strings which are allocated to spots on the global array. If you strcpy a string that's too long you can get a buffer overflow which will break the memory system. As such I would encourage people to get in the practice of doing it manually any ways.FDARI wrote:Blzut3: The user can manually call strlen to verify that the call should not fail based on string length, that is true. I thought you meant that the compiler could.
Like I implied I don't really have a problem with having a different return value, since I'll probably be handling it through function overloading in ACC++, but it seems like a bad idea. if(strcpy()) should either be valid or invalid, not determined by the type of array.
-
- Lead GZDoom+Raze Developer
- Posts: 48597
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ACS dynamic parameter strings
FDARI wrote:While it may not be the best approach, it is not nonsense. I am suggesting that the compiler should take three slightly different functions, and present them through a common interface.
To satisfy the interface "int strcpy(array,...)" (return type is the debated element here) it would need a result at the end of all code paths. However, it is not technically necessary for that return value to be the product of one of the strcpy-pcodes.
It may not be necessary but it's incredibly sloppy to do that. Give all 3 versions a return code and be done with it.
Most scripters won't have the technical knowledge to understand the difference and would (rightfully) declare this stupid.
Blzut3 wrote:If you strcpy a string that's too long you can get a buffer overflow which will break the memory system. As such I would encourage people to get in the practice of doing it manually any ways.
Add checks to prevent the buffer overflows. This is not C++ so it should have saveguards in place.
-
- Posts: 1097
- Joined: Tue Nov 03, 2009 9:19 am
Re: ACS dynamic parameter strings
I have no intention of writing code that goes through with a function that could corrupt memory. ZDoom.exe will require internal checks for that. And the compiler knows what you instruct it to know.
The compiler knows the context of the call (expression that must provide a value, statement), and therefore knows whether a return value is required or unwanted.
The compiler can branch based on this knowledge, and knowledge of which pcode it has applied. Example post processing for token "strcpy":The post-processing would look different if it were split into the general statement-evaluator and the general expression-evaluator, instead of merged into the above segment, but I just wanted to demonstrate what my english can't get across.
In short: The only people who will be concerned with the difference between the underlying pcodes are the programmers of Zdoom.exe and ACC.exe. The common interface presented by ACC.exe is specifically designed not to involve scripters in this process.
The compiler knows the context of the call (expression that must provide a value, statement), and therefore knows whether a return value is required or unwanted.
The compiler can branch based on this knowledge, and knowledge of which pcode it has applied. Example post processing for token "strcpy":
Code: Select all
switch (pcode) // this would be in ACC.exe
{
case PCD_STRCOPY_LEVEL:
// PCD_STRCOPY_LEVEL is known by the programmer, and therefore the program, to have a return value
if (!returnValue) PC_AppendCmd(PCD_DROP);
// if no return value is required, add instruction to drop the returned value
break;
default:
// remaining functions are known not to have return values
if (returnValue) { PC_AppendCmd(PCD_PUSHBYTE); PC_AppendByte(1); }
}
In short: The only people who will be concerned with the difference between the underlying pcodes are the programmers of Zdoom.exe and ACC.exe. The common interface presented by ACC.exe is specifically designed not to involve scripters in this process.
-
-
- Posts: 3108
- Joined: Wed Nov 24, 2004 12:59 pm
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ACS dynamic parameter strings
I was referring to ACS++'s implementation of malloc/free which if you recall I'm doing without any modifications to ZDoom.FDARI wrote:I have no intention of writing code that goes through with a function that could corrupt memory. ZDoom.exe will require internal checks for that. And the compiler knows what you instruct it to know.
-
- Lead GZDoom+Raze Developer
- Posts: 48597
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ACS dynamic parameter strings
FDARI wrote:I have no intention of writing code that goes through with a function that could corrupt memory. ZDoom.exe will require internal checks for that. And the compiler knows what you instruct it to know.
The compiler knows the context of the call (expression that must provide a value, statement), and therefore knows whether a return value is required or unwanted.
The compiler can branch based on this knowledge, and knowledge of which pcode it has applied. Example post processing for token "strcpy":The post-processing would look different if it were split into the general statement-evaluator and the general expression-evaluator, instead of merged into the above segment, but I just wanted to demonstrate what my english can't get across.Code: Select all
switch (pcode) // this would be in ACC.exe { case PCD_STRCOPY_LEVEL: // PCD_STRCOPY_LEVEL is known by the programmer, and therefore the program, to have a return value if (!returnValue) PC_AppendCmd(PCD_DROP); // if no return value is required, add instruction to drop the returned value break; default: // remaining functions are known not to have return values if (returnValue) { PC_AppendCmd(PCD_PUSHBYTE); PC_AppendByte(1); } }
In short: The only people who will be concerned with the difference between the underlying pcodes are the programmers of Zdoom.exe and ACC.exe. The common interface presented by ACC.exe is specifically designed not to involve scripters in this process.
Why do you so persistently insist on this nonsense? The code you posted alone is proof enough for me that this is needlessly wonky. You even have to make the compiler more complicated and what for?
Return the number of copied characters for all 3 versions and be done with it.
-
- Posts: 1097
- Joined: Tue Nov 03, 2009 9:19 am
Re: ACS dynamic parameter strings
I do not insist on the nonsense itself. However, I persist in reiterating it until I am certain that the answer entails no misconception about what I am suggesting. I am now convinced, as there is no incorrect assumption in your reply.
Noted. Moving on.
The next question: What would we use internally in zdoom? How much is this function worth if it works by copying characters from a string to a an array of 32-bit integers through a C++ loop? Fewer pcodes (light reduction on memory use and evaluations)?
What are our chances and benefits of using a real strcpy or memcpy?
I'm taking a look at the array storage types now, to see what answers I myself come up with. If we find a means to use real strcpy, we also need to make the data usable afterwards. Array printing assumes one character per int.
EDIT: World/global array is TMap sorted on integer key? We'll probably have to stick to the iterated assignment of char to int. Level-arrays seem more workable, but that doesn't mean there's a good way to use actual strcpy.
Spoiler: Still..."Return the number of copied characters for all 3 versions and be done with it."
Noted. Moving on.
The next question: What would we use internally in zdoom? How much is this function worth if it works by copying characters from a string to a an array of 32-bit integers through a C++ loop? Fewer pcodes (light reduction on memory use and evaluations)?
What are our chances and benefits of using a real strcpy or memcpy?
I'm taking a look at the array storage types now, to see what answers I myself come up with. If we find a means to use real strcpy, we also need to make the data usable afterwards. Array printing assumes one character per int.
EDIT: World/global array is TMap sorted on integer key? We'll probably have to stick to the iterated assignment of char to int. Level-arrays seem more workable, but that doesn't mean there's a good way to use actual strcpy.
-
- Lead GZDoom+Raze Developer
- Posts: 48597
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ACS dynamic parameter strings
Don't bother with strcpy.
Since in all cases you are copying from a byte array to an integer array any attempt to 'optimize' by using strcpy will cost you more than you might ever save.
Since in all cases you are copying from a byte array to an integer array any attempt to 'optimize' by using strcpy will cost you more than you might ever save.