Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script compiler: consider implementing int-float type casts as operators / opcodes #2593

Open
ivan-mogilko opened this issue Nov 26, 2024 · 2 comments

Comments

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Nov 26, 2024

There are 2 reasons beyond this proposal:

  • Syntactically operators may be easier to type (this may be argued though), e.g. having (float)int_variable instead of IntToFloat(int_variable);
  • Having a typecast as an opcode is faster than a engine API call (see comparison below). Which is not a big deal for an occasional function call, but may make a difference in case where you need to process heaps of data and convert results of computations to large amount of data objects (or object properties).

Comparison in opcodes:
Calling a static function commonly generates following set of commands:

PUSHREAL   (done *for each function arg*, which is 1 in case of IntToFloat, and 2 in case of FloatToInt)
NUMFUNCARGS
LITTOREG    (fixups to get func addr on a fly, pushes func addr to AX)
CALLEXT      (makes a function call)
SUBREALSTACK (unwinds a stack after returning from a function)

In case the type cast is implemented as opcode, this will be substituted with simply something like

INT2FLOAT  regN (takes a int value from regN and writes a float value into the same regN)

So this is going to be 5 times less opcodes, but difference in execution time may be even higher, as some of the function call opcodes do extra stuff.

Note that the FloatToInt cannot be fully substituted by an opcode, as it need to support different rounding styles. We may either keep it, or replace by a Round function instead, as was suggested in this comment.

First of all, what may be done as an experiment, to measure difference in performance: instead of implementing a (type) cast operator right away, the compiler may substitute function call with these new opcodes when meets IntToFloat and FloatToInt. Then this is tested with a script which does lots of these conversions in a row, to see if we may gain a noteable performance update from this or not.

@fernewelten
Copy link
Contributor

For float-to-int conversions, we could invent an opcode that takes the rounding direction as a parameter. Say
REAL2INT reg rdir
where reg is a register such as AX and rdir is a small integer that encodes eRoundDown, eRoundUp, and eRoundNearest.

The compiler could be taught to recognize the functions IntToFloat() and FloatToInt() and emit Bytecode statements instead of function calls whenver it sees calls to them. But of course, this kind of thing introduces clutter into the compiler.

@ivan-mogilko
Copy link
Contributor Author

ivan-mogilko commented Dec 10, 2024

I don't think it's wise to substitute function calls with opcodes in compiler, because API functions are a subject to changes, they may be expanded by either adding new parameter values, or even more parameters, which will break compatibility with both compiler and script interpreter.
There may be other reasons, not obvious at the first glance.

If such conversion opcodes would be implemented, I'd rather suggest having new keywords for them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants