About: Tail call is a research topic. Over the lifetime, 117 publications have been published within this topic receiving 2043 citations. The topic is also known as: tail-recursive & tail-end recursion.
TL;DR: STAL is presented, an extension of TAL with stack constructs and stack types to support the stack allocation style and it is shown that STAL is sufficiently expressive to support languages such as Java, Pascal, and ML; constructs such as exceptions and displays; and optimizations such as tail call elimination and callee-saves registers.
Abstract: In previous work, we presented a Typed Assembly Language (TAL). TAL is sufficiently expressive to serve as a target language for compilers of high-level languages such as ML. This work assumed such a compiler would perform a continuation-passing style transform and eliminate the control stack by heap-allocating activation records. However, most compilers are based on stack allocation. This paper presents STAL, an extension of TAL with stack constructs and stack types to support the stack allocation style. We show that STAL is sufficiently expressive to support languages such as Java, Pascal, and ML; constructs such as exceptions and displays; and optimizations such as tail call elimination and callee-saves registers. This paper also formalizes the typing connection between CPS-based compilation and stack-based compilation and illustrates how STAL can formally model calling conventions by specifying them as formal translations of source function types to STAL types.
TL;DR: This work presents a new semantics for stack inspection based on a belief logic and its implementation using the calculus of security-passing style which addresses the concerns of traditional stack inspection.
Abstract: In order to run untrusted code in the same process as trusted code, there must be a mechanism to allow dangerous calls to determine if their caller is authorized to exercise the privilege of using the dangerous routine. Java systems have adopted a technique called stack inspection to address this concern. But its original definition, in terms of searching stack frames, had an unclear relationship to the actual achievement of security, overconstrained the implementation of a Java system, limited many desirable optimizations such as method inlining and tail recursion, and generally interfered with interprocedural optimization. We present a new semantics for stack inspection based on a belief logic and its implementation using the calculus of security-passing style which addresses the concerns of traditional stack inspection. With security-passing style, we can efficiently represent the security context for any method activation, and we can build a new implementation strictly by rewriting the Java bytecodes before they are loaded by the system. No changes to the JVM or bytecode semantics are necessary. With a combination of static analysis and runtime optimizations, our prototype implementation showes reasonable performance (although traditional stack inspection is still faster), and is easier to consider for languages beyond Java. We call our system SAFKASI (the Security Architecture Formerly Known as Stack Inspection).
TL;DR: STAL is a variant of Typed Assembly Language with constructs and types to support a limited form of stack allocation and the type system of STAL ensures that a wide class of errors cannot occur at run time, and therefore the language can be adapted for use in certifying compilers where security is a concern.
Abstract: This paper presents STAL, a variant of Typed Assembly Language with constructs and types to support a limited form of stack allocation. As with other statically-typed low-level languages, the type system of STAL ensures that a wide class of errors cannot occur at run time, and therefore the language can be adapted for use in certifying compilers where security is a concern. Like the Java Virtual Machine Language (JVML), STAL supports stack allocation of local variables and procedure activation records, but unlike the JVML, STAL does not pre-suppose fixed notions of procedures, exceptions, or calling conventions. Rather, compiler writers can choose encodings for these high-level constructs using the more primitive RISC-like mechanisms of STAL. Consequently, some important optimizations that are impossible to perform within the JVML, such as tail call elimination or callee-saves registers, can be easily expressed within STAL.
TL;DR: This paper presents a simple but flexible Hoare-style framework for modular verification of assembly code with all kinds of stackbased control abstractions, including function call/return, tail call, setjmp/longjmp, weak continuation, stack cutting, stack unwinding, multi-return function call, coroutines, and thread context switch.
Abstract: Runtime stacks are critical components of any modern software--they are used to implement powerful control structures such as function call/return, stack cutting and unwinding, coroutines, and thread context switch. Stack operations, however, are very hard to reason about: there are no known formal specifications for certifying C-style setjmp/longjmp, stack cutting and unwinding, or weak continuations (in C--). In many proof-carrying code (PCC) systems, return code pointers and exception handlers are treated as general first-class functions (as in continuation-passing style) even though both should have more limited scopes.In this paper we show that stack-based control abstractions follow a much simpler pattern than general first-class code pointers. We present a simple but flexible Hoare-style framework for modular verification of assembly code with all kinds of stackbased control abstractions, including function call/return, tail call, setjmp/longjmp, weak continuation, stack cutting, stack unwinding, multi-return function call, coroutines, and thread context switch. Instead of presenting a specific logic for each control structure, we develop all reasoning systems as instances of a generic framework. This allows program modules and their proofs developed in different PCC systems to be linked together. Our system is fully mechanized. We give the complete soundness proof and a full verification of several examples in the Coq proof assistant.
TL;DR: The Functional Abstract Machine (Fam) is a stack machine designed to support functional languages on large address space computers which has been optimized to allow very fast function application and the use of true stacks.
Abstract: The Functional Abstract Machine (Fam) is a stack machine designed to support functional languages on large address space computers It can be considered a SECD machine [1] which has been optimized to allow very fast function application and the use of true stacks (as opposed to linked lists) The machine qualifies to be called functional because it supports functional objects (closures, which are dynamically allocated and garbage collected), and aims to make function application as fast as, say, taking the head of a list All the optimization and support techniques which make application slower are strictly avoided, while tail recursion and pattern-matching calls are supported Restricted side effects and arrays are provided, but they are less efficient than one might expect Moreover the performance of the proposed garbage collector deteriorates in the presence of large numbers of updatable objects The machine is intended to make compilation from high level languages easy and regular, by providing a rich and powerful set of operations and an open-ended collection of data types This richness of types can also facilitate portability, because every type can be independently implemented in different ways However the number of machine instructions tends to be high, and in general there is little concern for minimality The instructions of the machine are not supposed to be interpreted, but assembled into machine code and then executed This explains why no optimized special-case operations are provided; special cases can be easily detected at assembly time For efficiency considerations, the abstract machine is not supposed to perform runtime type checking (even if a hardware implementation of it might), and hence it is not type-safe Moreover, as a matter of principle, there is no primitive to test the type of an object; the correct application of machine operations should be guaranteed by typechecking in the source language Where needed, the effect of run-time typechecking can be achieved by the use of variant (ie tagged) data types