|WikiProject Computing||(Rated Start-class)|
- 1 subroutine call techniques: All code is threaded code?
- 2 types of subroutine-call instructions supported by hardware
- 3 Brad Rodriquez's articles
- 4 modern CPU call
- 5 some redundancies cannot be eliminated by subroutines
- 6 the very early days of computers
- 7 development of threaded code
- 8 Notation
- 9 Why examples in C?
- 10 Example from register based Parrot VM
subroutine call techniques: All code is threaded code?
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.
- 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)
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)
- 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)
- ITC above should refer to DTC; sorry Alex 20:23, 27 March 2006 (UTC)
types of subroutine-call instructions supported by hardware
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)
- Yes; see [Stack machine] and hardware specifically designed to run threaded code. Alex 12:03, 27 March 2006 (UTC)
Brad Rodriquez's articles
Could someone add a link to Brad Rodriquez's "Moving Forth" articles? http://www.zetetics.com/bj/papers/
Also, I think 'w' is 'working register' not 'word pointer'.
modern CPU call
Did I hear someone claim that "not all modern cpus have call instructions" ?
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.
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 (talk • contribs) 20:41, 20 July 2015 (UTC)
some redundancies cannot be eliminated by subroutines
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?
- 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 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)
the very early days of computers
A recent edit  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?
development of threaded code
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 (  ) 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.
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)
Why examples in C?
Given Forth is the most common example of a threaded code implementation, why are the examples in C rather than assembly or pseudo-code?
Example from register based Parrot VM
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)