Implementation of SYSTEM.VAL()

Kernel, Loader, code execution and working with memory
Zorko
Posts: 26
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine
Contact:

Implementation of SYSTEM.VAL()

Post by Zorko »

David C W Brown wrote:FYI I just tested my example in black box component builder:

Code: Select all

MODULE test;
IMPORT StdLog, SYSTEM;

PROCEDURE Do*;
VAR i,j: INTEGER; l: LONGINT;
BEGIN
i := 1; j := -1;
l := SYSTEM.VAL(LONGINT,i);
StdLog.Int(l); StdLog.Ln
END Do;

END test.
test.Do

And it logs the value '27839728904568833'.

Arghh!

Is anyone proposing that this behaviour is correct?
Surely not?

-- Dave.
User avatar
Ivan Denisov
Posts: 362
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Implementation of SYSTEM.VAL()

Post by Ivan Denisov »

Yes, it is correct behavior. You are making manipulation with RAM, that is leading to unexpected results.

That is not correct type transformation. If you want to make longint from integer, use just:

Code: Select all

l := i
That this lead to correct type transformation.

Code: Select all

l := LONG(i);
Is also correct.
User avatar
Robert
Posts: 177
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Implementation of SYSTEM.VAL()

Post by Robert »

Zorko wrote:And it logs the value '27839728904568833'.
The hex for "27839728904568833" is "62E81600000001", so the bottom 32 bits are "1" as expected. What the top 32 bits are is undefined in the "Platform Specific Issues" document, and quite likely will vary from one compiler to another. Actually there is no reason to suppose another compiler will have a "SYSTEM.VAL" function.
dcwbrown
Posts: 2
Joined: Mon Aug 15, 2016 11:20 am

Re: Implementation of SYSTEM.VAL()

Post by dcwbrown »

Thanks. (Obviously) I was not expecting that. Is this documented anywhere?

I ask because I have found no documentation on VAL in any Oberon system beyond the following statement:

VAL(T, x) T, x: any type T x interpreted as of type T

It doesn't say what aspect of x - specifically whether it is the memory beginning where x begins (as I now understand is the case), or the value of x (which I had believed.)
Why would I make this mistake? Because the only place I have found more details is in Wirth's Modula-2 document ETH-3135-01, which says:

VAL(T,x) the value with the ordinal number x and with type T.

So to be clear, Component Pascal's VAL has the same type signature as Modula's, but is almost entirely different.

So
-- Just to confirm - the extreme difference form Modula is intentional, right?
-- Is it specified anywhere that the behaviour as reinterpretation of memory rather than value?

Thanks -- Dave.
User avatar
Robert
Posts: 177
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Implementation of SYSTEM.VAL()

Post by Robert »

SYSTEM.VAL is documented in "Platform Specific Issues". I have always implicitly understood this as "over-riding type checking", or "reinterpreting memory", rather than as a real type conversion. But it does not say so in as many words!.
Since T & x in "VAL(T,x)" can be any type, not just those known to the compiler writers, I don't know what else it could do.
(This document is specific to the Oms Windows compiler. It does not apply to other operating systems or other compilers.)
Module SYSTEM contains certain procedures that are necessary to implement low-level operations. It is strongly recommended to restrict the use of these features to specific low-level modules, as such modules are inherently non-portable and usually unsafe. SYSTEM is not considered as part of the language Component Pascal proper.
VAL is NOT part of the language Component Pascal, so it is incorrect to say CP defines it differently to ..., as it does not define it at all.
dcwbrown
Posts: 2
Joined: Mon Aug 15, 2016 11:20 am

Re: Implementation of SYSTEM.VAL()

Post by dcwbrown »

Thanks for making it clear. That does make sense.
-- Dave.
Zorko
Posts: 26
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine
Contact:

Re: Implementation of SYSTEM.VAL()

Post by Zorko »

Dear all,

We are mentioned a specific feature that may remain unknown to many users.

For SYSTEM.VAL(TYPE, 'value') David proposes to produce a warning when SIZE(TYPE) > SIZE(type of 'value').

Since SYSTEM.VAL works with a value in memory, it may make sense to protect your applications from failure, because SYSTEM.VAL is not intended to access a data address that placed out of a needed 'value'.
Josef Templ
Posts: 262
Joined: Tue Sep 17, 2013 6:50 am

Re: Implementation of SYSTEM.VAL()

Post by Josef Templ »

Using different sizes would make sense inside an array or record,
i.e. where you have some knowledge about the memory layout.
Zorko
Posts: 26
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine
Contact:

Re: Implementation of SYSTEM.VAL()

Post by Zorko »

Therefore, I propose to produce warning, and not error. In the case of ignoring this warning, a programmer knows exactly what goes.

Is there a possibility to show a warning in BlackBox?
luowy
Posts: 87
Joined: Thu Dec 17, 2015 1:32 pm

Re: Implementation of SYSTEM.VAL()

Post by luowy »

Zorko wrote:Therefore, I propose to produce warning, and not error. In the case of ignoring this warning, a programmer knows exactly what goes.

Is there a possibility to show a warning in BlackBox?
yes,you can do it at DevCPB.StPar1

Code: Select all

		| valfn: (*SYSTEM.VAL*)	(* type is changed without considering the byte ordering on the target machine *)
				IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
				ELSIF x.typ.comp = DynArr THEN
					IF x.typ.untagged & ((p.typ.comp # DynArr) OR p.typ.untagged) THEN	(* ok *)
					ELSIF (p.typ.comp = DynArr) & (x.typ.n = p.typ.n) THEN
						typ := x.typ;
						WHILE typ.comp = DynArr DO typ := typ.BaseTyp END;
						tp1 := p.typ;
						WHILE tp1.comp = DynArr DO tp1 := tp1.BaseTyp END;
						IF typ.size # tp1.size THEN err(115) END
					ELSE err(115)
					END
				ELSIF p.typ.comp = DynArr THEN err(115)
				ELSIF (x.class = Nconst) & (f = String8) & (p.typ.form = Int32) & (x.conval.intval2 <= 5) THEN
					i := 0; n := 0;
					WHILE i < x.conval.intval2 - 1 DO n := 256 * n + ORD(x.conval.ext[i]); INC(i) END;
					x := NewIntConst(n)
				ELSIF (f IN {Undef, NoTyp, NilTyp}) OR (f IN {String8, String16}) & ~(DevCPM.java IN DevCPM.options) THEN err(111)
				END ;
				IF (x.class = Nconst) & (x.typ = p.typ) THEN	(* ok *)
				ELSIF (x.class >= Nconst) OR ((f IN realSet) # (p.typ.form IN realSet))
						OR (DevCPM.options * {DevCPM.java, DevCPM.allSysVal} # {}) THEN
					t := DevCPT.NewNode(Nmop); t.subcl := val; t.left := x; x := t
				ELSE x.readonly := FALSE; 
					IF p.typ.size>x.typ.size THEN 
						DevCPM.err(-800); (* small than -700  *)
						DevCPM.LogWLn();DevCPM.LogWStr("SYSTEM.VAL(BigSize,SmallSize)") ;DevCPM.LogWLn();
					END;
				END ;
				x.typ := p.typ; p := x
		| movefn: (*SYSTEM.MOVE*)
luowy
Post Reply