Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why not store into literals?

96 views
Skip to first unread message

luserXtrog

unread,
Dec 19, 2010, 4:25:59 AM12/19/10
to
from:
http://www.ghostscript.com/doc/current/Ps-style.htm

4.1 Restrictions

If you need to store a value temporarily, don't write into a literal
in the code, as in this fragment to show a character given the
character code:

( ) dup 0 4 -1 roll put show

Instead, allocate storage for it:

1 string dup 0 4 -1 roll put show


Any idea why?
All memory comes from VM, right? token calls string, too, right?
What's the diff?

--
<it's o so quiet!>

ThomasW

unread,
Dec 19, 2010, 4:59:23 AM12/19/10
to


Probably because of this effect:

/stringdemo {
(1) 0 33 put
} def

(stringdemo procedure initially looks like this:)=
/stringdemo load ==

(Now it's executed and "modifies itself")=
stringdemo

(and looks like this afterwards:)=
/stringdemo load ==


The output is:

stringdemo procedure initially looks like this:
{(1) 0 33 put}
Now it's executed and "modifies itself"
and looks like this afterwards:
{(!) 0 33 put}


But if you know what you're doing, I think it can make sense,
especially to prevent allocating and throwing away memory for a ton of
possibly large strings.

Thomas W.

Helge Blischke

unread,
Dec 19, 2010, 5:14:43 AM12/19/10
to
luserXtrog wrote:

Perhaps because string literals are independent of save and restore ?

Helge

Helge Blischke

unread,
Dec 19, 2010, 5:14:43 AM12/19/10
to
luserXtrog wrote:

Perhaps because string literals are independent of save and restore ?

Helge

luserXtrog

unread,
Dec 19, 2010, 5:27:53 AM12/19/10
to

Oh, is that still true? I saw mention of it in the red book, but the
sense I got was "we're just about to fix this". So are strings in a
different part of memory from other composites?

luserXtrog

unread,
Dec 19, 2010, 5:41:05 AM12/19/10
to

Well, yeah. But if you're already modifying contents of procedures,
you could easily have the initialing version redefine itself to
a preinitialized version, extracting the literal and stuffing it
into the new array.

/stringdemo {
(1) dup 0 33 put
/stringdemo { 0 show } dup 3 index 0 exch put def
show
} def

Helge Blischke

unread,
Dec 19, 2010, 6:53:33 AM12/19/10
to
luserXtrog wrote:

The PLRM, 3rd ed., states on section 3.7.3 Save and Restore on page 61:

Specifically, restore does
the following:
• Discards all objects in local VM that were created since the corresponding
save,
and reclaims the memory they occupied
• Resets the values of all composite objects in local VM, except strings, to
their
state at the time of the save
...

And Ghostscript behaves as expected (in one project, it took pains for me to
internalize this).

Helge

John Reiser

unread,
Dec 19, 2010, 2:09:43 PM12/19/10
to
> Why not store into literals?

To preserve the option for the PostScript language processor
to store literals in some special way(s) that may be more efficient
in time and/or space, or have other properties that may be desirable
depending on the implementation and/or environment. For example,
read-only storage or compressed storage, such as: common substrings
(especially tails) or deflated with all literals that are referenced
by objects in certain dictionaries, etc. Also, literals which
change value can be a maintenance nightmare. Containing the change
can be difficult.

--

luserXtrog

unread,
Dec 20, 2010, 1:06:05 AM12/20/10
to

That seems possible for languages in general, but the peculiarities
of postscript make it surprising here. And the document offers
no rationale whatever. I quoted the complete entry.

Perhaps code will make my skepticism more toothy.

(#) dup 0 63 put %1
1 string dup 0 63 put %2

For direct execution I see a clear advantage in %1.
But the situation does seem to change slightly in
a deferred execution.

/gimmeanA { (#) dup 0 63 put } def
/gimmeanewA { 1 string dup 0 63 put } def

Is it too lat to pick a different example? I don't
like either one. My imagination just stopped working.
Let me hunt down a real example. Maybe it's moot!

luserXtrog

unread,
Dec 20, 2010, 2:01:28 AM12/20/10
to

I think I begin to get it. Packed Arrays and Resources and
junk. It's all the stuff you just said, John, that I refused
to hear. It's all true!

My example refused to lead me to victory for the simple reason
that I was wrong. Prefering line %2 makes the memory usage
more explicit, and therefore more 'apparent' to both human
and computer interpretation.

Perhaps if I take my example one step further.

/gimmeanA { DUMMY dup 0 63 put } dup 0 (#) put def %5
/gimmeanewA { DUMMY dup 0 63 put } dup 0 1 string put def %6

I think %6 wins here.

luserXtrog

unread,
Dec 20, 2010, 3:58:44 AM12/20/10
to
On Dec 19, 4:14 am, Helge Blischke <h.blisc...@acm.org> wrote:

Well, that's reasonable, I suppose. The document is about style and
not rules. For extensions to the interpreter itself, yes; I agree
with the recommendation.

But for my kind of postscript -- hand-hacked documents -- I say
literals is fair game! execjob does a restore. String contents
are immune to save and restore: their existence is not.

--
(literal ) dup 5 (ate) putinterval

bugbear

unread,
Dec 20, 2010, 4:50:34 AM12/20/10
to
luserXtrog wrote:

>>
>> Perhaps because string literals are independent of save and restore ?
>>
>> Helge
>
> Oh, is that still true? I saw mention of it in the red book, but the
> sense I got was "we're just about to fix this". So are strings in a
> different part of memory from other composites?

I suspect enough code grew up that relied on this (
either deliberately or accidently) that changing
it was deemed to have too high a price.

The reason (in the original code) was almost certainly
granularity - changes to dictionaries and arrays (composite objects)
are at the level of objects, whilst string changes are at the level
of bytes.

BugBear

luserXtrog

unread,
Dec 20, 2010, 10:31:32 PM12/20/10
to

Rats! My interpreter doesn't do this. save makes a copy of the entire
VM, and restore discards the topmost copy.

So does each object carry around a pointer to its earlier version
or would there be some kind of cross-reference structure tying
different versions together?

0 new messages