From radford at cs.toronto.edu  Fri Aug 21 22:21:26 2015
From: radford at cs.toronto.edu (Radford Neal)
Date: Fri, 21 Aug 2015 16:21:26 -0400
Subject: [Rd] Problems with embedded R, ReplDLL
Message-ID: <20150821202126.GA13024@cs.toronto.edu>

Along with getting pqR to work on Windows, I've also been testing it
in the context of embedded R, and in the process have found some
problems with the examples given of embedded R use.

One problem can be seen in R_ReplDLLinit, in src/main/main.c:


void R_ReplDLLinit(void)
{
    SETJMP(R_Toplevel.cjmpbuf);
    R_GlobalContext = R_ToplevelContext = R_SessionContext = &R_Toplevel;
    R_IoBufferWriteReset(&R_ConsoleIob);
    prompt_type = 1;
    DLLbuf[0] = DLLbuf[CONSOLE_BUFFER_SIZE] = '\0';
    DLLbufp = DLLbuf;
}


The call of SETJMP makes no sense.  Nothing that follows in this
function can possibly cause a long jump.  The use of R_ReplDLLinit is
illustrated in the R Extensions manual (doc/manual/R-exts.texi):


        R_ReplDLLinit();
        while(R_ReplDLLdo1() > 0) {
        /* add user actions here if desired */
        }


Note that the R_ReplDLLdo1 function does not call SETJMP.


Amazingly, however, the combination sometimes seems to work!  When a
long jump is taken during evaluation of an expression initiated by
R_ReplDLLdo1, the stack is restored to the value suitable for the
now-non-existent stack frame for R_ReplDLLinit, and execution of the
statements in R_ReplDLLinit then continues after the SETJMP.  Likely,
none of these statements actually refers to the non-existent stack
frame (seeing as this function has no parameters and no local
variables), so nothing disastrous occurs, and in the end the procedure
return code at the end of R_ReplDLLinit has the effect of doing a
return from R_ReplDLLdo1, which is more-or-less the desired result.


Obviously, one does not want a program to "work" for such reasons,
which may cease to apply with any change to how the C compiler
generates code.  The current development version of pqR has a
different version of R_ReplDLLdo1, which calls SETJMP itself, but this
version is tied to other rationalizations of the Repl functions in the
development version of pqR.  The embedded R examples and tests have
various other problems that are fixed in the current development
branch of pqR (branch 44 at the moment).  R Core might want to take a
look there, or at the next version of pqR, which will be released
soon.

   Radford Neal



[Rd] Problems with embedded R, ReplDLL
Radford Neal