Jump to content

Talk:Threaded code

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

subroutine call techniques: All code is threaded code?

[edit]

The article currently claims

Threaded code is used in the Forth and early versions of the B programming languages, as well as many implementations of FORTRAN, BASIC, COBOL and other languages for small minicomputers.

then later

Early compilers for ALGOL, Fortran, Cobol and some Forth systems often produced subroutine-threaded code.

It sounds like someone was confused by the people who call native machine language, "subroutine threaded code", which most people would say is the .opposite of threaded code. If "subroutine threaded code" is a kind of threaded code, then practically all code is threaded code of one kind or another. (The only exception is code that doesn't have *any* subroutines, right?).

I think Chuck Moore developed the term "threaded code" to describe Forth, meaning indirect threaded code or direct threaded code.

Did any of these other compiler/interpreters really generate indirect threaded code or direct threaded code ? I know some BASIC and PASCAL compilers generate "p-code" ...

--DavidCary 12:37, 13 July 2005 (UTC)[reply]

I am very interested in the variety of subroutine call techniques (what some people call the kinds of "threading model").

There's a nice discussion developing here, but it's starting to drown out what most people think of as "threaded code" (indirect-threaded code and direct-threaded code).

Is there a better article somewhere else (or a good name for an article, if one doesn't exist yet) to talk about subroutine call techniques in general, leaving this article to focus on ITC and DTC ?

--DavidCary 12:37, 13 July 2005 (UTC)[reply]

Subroutine threaded code is different from native code in that everything is a call; including to constructs like IF. Take this code in Forth;
 : X IF ." True" THEN ... etc
An STC potentially generates (numbers are there to discuss in text)
 (1)  CALL <routine to put "label" on return stack>
 (2)  CALL IF
 (3)  CALL <routine to put address of string "True" on the stack>
 (4)  CALL ."
 (5) <label>:  
 (6)  CALL THEN
      ... etc
(1) "tucks" the address of the label <label> on the return stack by popping the caller's return address, pushing address of <label> and returning. (2) IF pops and checks the top of the data stack; if it's zero, then jump to label, else return. And so on. (6) is in fact a no-op, but it's sometimes generated so that the code can be decompiled easily by printing off the labels in the symbol table (called a dictionary in Forth) associated with the CALLed address.
There are very few Forths that use STC in this extreme form, and a blend between STC and NCC (native code compilation) is normally used. An ITC is the same code, but with addresses only and no CALL opcode; a small VM interpreter does the call/return management. Alex 12:00, 27 March 2006 (UTC)[reply]
ITC above should refer to DTC; sorry Alex 20:23, 27 March 2006 (UTC)[reply]

types of subroutine-call instructions supported by hardware

[edit]

I removed In some computers there are different types of subroutine-call instructions using different lengths of addresses. In these, the programmers could often arrange to use a shorter form by using threaded code. because I don't see how it is relevant -- a threaded call is always shorter than even the shortest subroutine-call instruction.

I removed Threading is ... processed by ... the CPU (B), because the CPUs I am familiar with cannot directly process threaded code (except for so-called "subroutine threaded code"). But it is theoretically possible that some CPU has special hardware to directly process threaded code -- does such a CPU really exist ? --DavidCary 12:37, 13 July 2005 (UTC)[reply]

Yes; see Stack machine and hardware specifically designed to run threaded code. Alex 12:03, 27 March 2006 (UTC)[reply]
Can anyone give me a direct link to "hardware specifically designed to run threaded code"?
I looked at stack machine, and I see "threaded code" mentioned twice.
Once in a section describing interpreters for virtual stack machines running on pre-existing register-machine hardware, which is clearly *not* "special hardware to directly process threaded code".
Once in a section describing hybrid machines that combine register-machine architecture with an additional "memory address mode which emulates the push or pop operations of stack machines", which I admit is *helpful* in an interpreter that processes threaded code, but as far as I can tell still *indirectly*.
Is there some other section that *alludes* to "threaded code" without specifically mentioning that phrase?
Did perhaps the stack machine article once described hardware specifically designed to directly run threaded code, but that information somehow got lost in the 14 years (!) since the above comments?
--DavidCary (talk) 22:22, 1 July 2020 (UTC)[reply]
Well, the "PC=(A)" and "PC=(C)" instructions on the HP Saturn microprocessors are specifically designed to run RPL ( specifically, see eg. the threaded code RPL section ), which is a combination of direct and indirect threaded code. Jdbtwo (talk) 19:46, 2 July 2020 (UTC)[reply]

Brad Rodriquez's articles

[edit]

Could someone add a link to Brad Rodriquez's "Moving Forth" articles?

https://www.bradrodriguez.com/papers/moving1.htm

Also, I think 'w' is 'working register' not 'word pointer'.

—The preceding unsigned comment was added by 68.60.59.250 (talkcontribs) 13:17, 20 April 2006 (UTC2)

modern CPU call

[edit]

Did I hear someone claim that "not all modern cpus have call instructions"[1] ?

Certainly many recent homebrew CPU designs ( Wikibooks:Microprocessor Design/Wire Wrap ) don't have a call instruction -- but most people call them "retro" rather than "modern".

Which CPU would that be? I can't think of *any* CPU built after the 1976 RCA 1802 that didn't have a call instruction.

--68.0.124.33 (talk) 18:33, 18 January 2008 (UTC)[reply]

The Parallax_Propeller has a 'CALL' assembler instruction (which shares the instruction bits with the op-code of 'JMP'), but no stack pointer (that instruction cannot be used for re-entrant code), so I think it qualifies ;-} — Preceding unsigned comment added by Guenthert (talkcontribs) 20:41, 20 July 2015 (UTC)[reply]

some redundancies cannot be eliminated by subroutines

[edit]

Recently, someone changed the last sentence of

Some early computers such as the RCA 1802 required several instructions to call a subroutine. In the top-level application and in many subroutines, that sequence is repeated over and over again, only the subroutine address changing from one call to the next. Using expensive memory to store the same thing over and over again seems wasteful -- is there any way to store this information exactly once?

to

Using expensive memory to store the same thing over and over again seemed wasteful; using subroutines allowed the code to be stored once, and called from many different locations.

I reverted that edit, even though that new last sentence is *usually* true, in isolation -- *usually* redundant sequences of instructions can be shortened by using subroutines.

However, it is not possible to "use subroutines" to eliminate the particular redundant sequences mentioned in the previous sentence. (Or am I missing something?)

The entire point of the article is that there *is* a way to "store this information exactly once" -- threaded code -- and the various kinds of threading are various ways of implementing that goal.

I suspect that lots of people skim over that last question and misunderstand it -- how can I improve the article by clarifying it? --68.0.124.33 (talk) 14:40, 30 May 2008 (UTC)[reply]

  • I agree that the statement is a bit vague; I had to reread it several times to figure out what it actually meant. I think that phrasing it as a question makes it more ambiguous, and also doesn't really make sense in terms of style - which is why I changed it before. I see now, though, that what I changed it to doesn't really mean the same thing.
How about simply:
Some early computers such as the RCA 1802 required several instructions to call a subroutine. In the top-level application and in many subroutines, that sequence is repeated over and over again, only the subroutine address changing from one call to the next. Threaded code was invented to reduce this redundancy.
mistercow (talk) 06:37, 12 June 2008 (UTC)[reply]
Done. But please feel free to clarify it even more. --68.0.124.33 (talk) 17:11, 18 June 2008 (UTC)[reply]

the very early days of computers

[edit]

A recent edit [2] implies that "threaded code" is a re-invention of something used "since the very early days of computers".

I admit to not knowing much about early mainframe computers. So:

  • Did this earlier technique have a name other than "threaded code"?
  • Was this earlier technique the same as what we would now call "threaded code", or was there something different about it?
  • Was this technique so very different from threaded code that it shouldn't even be mentioned on this "threaded code" article, and instead discussed on some other more relevant article?

--68.0.124.33 (talk) 05:32, 30 January 2009 (UTC)[reply]

development of threaded code

[edit]

This article could either:

  • (a) immediately present an example of threaded code, and try to explain how it works on its own terms, without getting sidetracked on bytecodes, or
  • (b) start with a brief detour describing an easier-to-understand "decode and dispatch interpreter". Then show a series of simple Wittgenstein's ladder steps (described using bytecode terminology) of "development" required to convert it into threaded code.

Which approach helps people better understand this subject?

At one time, this article used approach (b).

Alas, a well-meaning edit ( [3] ) chopped the first step or two out of that sequence. This leaves the "Development" section Threaded_code#Development with several confusing dangling references to "the bytecodes" and "the decode and dispatch interpreter described above" that no longer exists.

Would this article be easier to understand if we revert to approach (b), or if we delete those dangling references and try to switch to approach (a)? --DavidCary (talk) 18:23, 15 May 2011 (UTC)[reply]

I've switched to (a) but the dangling references remain in source (commented out), just in case. It might be prudent to move the text down, where a bytecode interpreter is in fact given after threaded code discussion is done. eritain (talk) 19:09, 12 June 2019 (UTC)[reply]

Notation

[edit]

This article uses some notation I haven't seen before, without explaining what it is or what it means, making the article difficult to understand. The notation looks a bit like C, but it's not C. Why has no-one else commented on this?--greenrd (talk) 11:21, 26 October 2013 (UTC)[reply]

Why examples in C?

[edit]

Given Forth is the most common example of a threaded code implementation, why are the examples in C rather than assembly or pseudo-code?

C and Forth are at opposite ends of the spectrum on so many issues. It just seems *wrong* to give examples of threaded code using C idioms.87.68.22.118 (talk) 19:39, 23 February 2014 (UTC)[reply]

Example from register based Parrot VM

[edit]

Simple example (in Parrot virtual machine source) with function base opcodes, switched opcode core and CGOTO core is examples/c/nanoparrot.c. I did some tests a long ago, see Nanoparrot. --mj41 (talk) 22:01, 30 October 2015 (UTC)[reply]

Psuedocode examples are confusing and possibly wrong

[edit]

Currently, the psuedocode examples are C-like enough that people might assume they follow the rules of C. However, each one of these examples falls victim to undefined behavior, more specifically, unsequenced modification and access. In order to clarify to the readers of the article the exact behavior of what this would look like in a C-like language, I believe we should rewrite the C-like pseudocode so that it does not contain what is considered undefined behavior in C. However, to try and work towards a better article, I would like to know if anybody has potentially better ideas for what could be done. I was thinking maybe switching pseudocode styles altogether? Thanks!

Bulbazord (talk) 04:10, 11 November 2016 (UTC)[reply]

I've suggested a syntax modification below: specifically, not using the & character for every array element, and switching from a C-switch style to a C-procedure style: I specifically consider the use of named blocks syntactically beneficial. 2602:301:7764:AC00:9ED:9E40:9294:D87 (talk) 22:43, 1 June 2019 (UTC)[reply]

Threading models and example syntax

[edit]

The section describing Direct Threaded code says the following:

This form is simple, but may have overheads because the thread consists only of machine addresses, so all further parameters must be loaded indirectly from memory.[1]

before later giving an example of direct-threaded code that contains inlined constants (A and B), in direct contradiction to the quote I've provided above. I propose the following wording be used in it's place:

This form is simple, but if the thread consists only of machine addresses, then all further parameters must be loaded indirectly from memory, which may impose overheads.


Additionally, a grammar similar to C (in particular, using switches) is used, but constants appear to be referenced via address, yet used as values! I advise replacing instances of &A or &B with simple A or B, and using a C-procedure style grammar instead of a C-switch grammar, perhaps with something like "jump" or "jump to" at the start of a reference to another piece of code, to clarify the manner in which the code in question is being used.

2602:301:7764:AC00:9ED:9E40:9294:D87 (talk) 22:39, 1 June 2019 (UTC)[reply]

References

Definition of threaded-interpreted language / TIL

[edit]

Abbr. "TIL" is not introduced (sub section RPL). It is probably for "threaded-interpreted language", but this is not defined (what is it precisely?).

Or threaded-interpretive language, not threaded-interpreted language?

--Mortense (talk) 18:25, 20 May 2021 (UTC)[reply]

I have reworded this paragraph to include a definition of the term. Yes, it's threaded interpretive language, although some people erroneously use threaded-interpreted language. --Matthiaspaul (talk) 19:55, 3 August 2023 (UTC)[reply]

Does "bit" mean "little"?

[edit]

The phrases "which reads the symbolic language a bit at a time" and "each bit exists in only one place" use the word "bit" which may be confused for the computing meaning, rather than e.g. "little". Just in case early machines did read single bits while interpreting, I opened this discussion rather than making the edit. 47.154.80.218 (talk) 18:49, 29 November 2022 (UTC)[reply]