Implementation of SYSTEM.VAL()

Kernel, Loader, code execution and working with memory

Implementation of SYSTEM.VAL()

Postby Zorko » Sun Aug 14, 2016 11:05 pm

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.
Zorko
 
Posts: 21
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine

Re: Implementation of SYSTEM.VAL()

Postby Ivan Denisov » Mon Aug 15, 2016 2:20 am

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
Ivan Denisov
 
Posts: 277
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: Implementation of SYSTEM.VAL()

Postby Robert » Mon Aug 15, 2016 9:01 am

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.
User avatar
Robert
 
Posts: 137
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Implementation of SYSTEM.VAL()

Postby dcwbrown » Mon Aug 15, 2016 11:37 am

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.
dcwbrown
 
Posts: 2
Joined: Mon Aug 15, 2016 11:20 am

Re: Implementation of SYSTEM.VAL()

Postby Robert » Mon Aug 15, 2016 1:52 pm

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.
User avatar
Robert
 
Posts: 137
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Implementation of SYSTEM.VAL()

Postby dcwbrown » Tue Aug 16, 2016 2:09 pm

Thanks for making it clear. That does make sense.
-- Dave.
dcwbrown
 
Posts: 2
Joined: Mon Aug 15, 2016 11:20 am

Re: Implementation of SYSTEM.VAL()

Postby Zorko » Sat Aug 20, 2016 10:00 am

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'.
Zorko
 
Posts: 21
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine

Re: Implementation of SYSTEM.VAL()

Postby Josef Templ » Mon Aug 22, 2016 9:53 am

Using different sizes would make sense inside an array or record,
i.e. where you have some knowledge about the memory layout.
Josef Templ
 
Posts: 242
Joined: Tue Sep 17, 2013 6:50 am

Re: Implementation of SYSTEM.VAL()

Postby Zorko » Mon Aug 22, 2016 2:03 pm

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?
Zorko
 
Posts: 21
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine

Re: Implementation of SYSTEM.VAL()

Postby luowy » Mon Aug 22, 2016 7:27 pm

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
luowy
 
Posts: 51
Joined: Thu Dec 17, 2015 1:32 pm

Next

Return to System

Who is online

Users browsing this forum: No registered users and 1 guest

cron