Skip to content

Commit

Permalink
tons of bug fixes, test pages now work stably on ubuntu using clean p…
Browse files Browse the repository at this point in the history
…ull from github
  • Loading branch information
gmbecker committed Apr 16, 2013
1 parent 58e13fd commit 732f473
Show file tree
Hide file tree
Showing 18 changed files with 1,272 additions and 386 deletions.
5 changes: 3 additions & 2 deletions R/NPAPI.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ NP_Invoke = function(...,
else
NA
}, convArgsEnum, convertArgs)

if(is.function(convertRet))
convRetEnum = getConvEnum("custom")
convRetEnum = getConvEnum("reference") #we apply our custom converter in R after the value is returned!!!
else
convRetEnum = getConvEnum(convertRet)

ret = .Call("R_NPAPI_Invoke", plug, obj, name, args, convArgsEnum, convArgsFuns, convRetEnum, keepResult)
if(is.function(convertRet))
{
print("convertRet function detected!")
print("applying custom convertRet function in R.")
ret = convertRet(ret)
}
ret
Expand Down
2 changes: 1 addition & 1 deletion R/Raphael.R
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ raphaelCDev = function(id = "raph_content", dim = c(400, 400), storage = new.env
assign("paper", tmp, env = storage)
print("Raphael C device paper created")
.Call("R_GD_raphaelDevice", storage, PluginInstance, as.integer(dim))
assign("devnum", dev.cur(), storage)
assign("devnum", dev.cur(), storage)
list(getPoints = function() get("points", storage),
getLines = function() get("lines", storage),
getPolyLines = function() get("polylines", storage),
Expand Down
27 changes: 27 additions & 0 deletions R/utilities.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ getSlotNames = function(obj)
names(getSlots(class(obj)))
}

checkForSlot = function(obj, name)
{
slots = getSlotNames(obj)
return(name %in% slots)
}
checkForField = function(obj, name)
{
fields = getFields(obj)
Expand Down Expand Up @@ -48,3 +53,25 @@ getJSMethodObj = function(obj)
stop("Unable to find a JSValueRef associated with obj")
ret
}

CheckForProperty = function(obj, prop)
{
tmp = TRUE
ret = FALSE
if (isRefClass(obj))
ret = checkForFieldorMethod(obj, prop)
else if (isS4(obj))
ret = checkForSlot(obj, prop)


if(!ret)
{
if( is(prop, "integer") || (is(prop, "numeric") && prop == floor(prop)))
ret = prop > 0 && prop <= length(obj)
else if (is(prop, "character"))
ret = prop %in% names(obj)
else
stop(paste("Cannot specify properties to check for via class", class(prop)))
}
return(ret)
}
2 changes: 1 addition & 1 deletion inst/NPAPI/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ R_LD_FLAGS=-L$(R_HOME)/lib -lR
OBJ_FILES = BasicPlugin.o WebREngine.o NPConversions.o WebRObject.o WebRFunction.o WebRMutex.o
npbasicplugin : $(OBJ_FILES)
ifeq ($(IS_MAC), 0)
cc $(CPPFLAGS) $(R_LD_FLAGS) $(LD_FLAGS) -shared $(OBJ_FILES) -o RBrowserPlugin.so
$(CXX) $(OBJ_FILES) -shared -o RBrowserPlugin.so $(CPPFLAGS) $(R_LD_FLAGS) $(LD_FLAGS)
else
#we need to make sure to clean every time because some stuff seems to be getting cached when it shouldn't
xcodebuild clean -configuration Debug -sdk macosx10.5 ARCHS="i386"
Expand Down
192 changes: 99 additions & 93 deletions inst/NPAPI/NPConversions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,70 @@

bool ConvertRToNP(SEXP val, NPP inst, NPNetscapeFuncs *funcs, NPVariant *ret, convert_t convRes)
{

fprintf(stderr, "Entering ConvertRToNP\n");fflush(stderr);
//If it is a promise we need the actual value.
int err = 0;
int numprot = 0;
bool canfree;
if(TYPEOF(val) == PROMSXP)
{
PROTECT(val = rQueue.requestRCall(val, R_GlobalEnv, &err, inst));
numprot = 1;
numprot++;
}
//Is it already a reference to an existing NP/JS object? If so just return that object!
if (CheckSEXPForJSRef(val, inst))
{
//XXX We shouldn't have to copy here, but do we really want to pass in double pointers?

*ret = *(NPVariant *) R_ExternalPtrAddr(GET_SLOT( val , Rf_install( "ref" ) ) );
return true;
}

if(convRes == CONV_COPY)
canfree = true;
}
else if(convRes == CONV_COPY)
{
MakeCopyRToNP(val, inst, funcs, ret);
return true;
canfree = true;
}
if(convRes == CONV_REF || convRes == CONV_CUSTOM)
else if(convRes == CONV_REF || convRes == CONV_CUSTOM)
{
MakeRRefForNP(val, inst, funcs, ret);
return true;
canfree = false;
}
else if (convRes == CONV_DEFAULT)
{

// I don't think we need this check here, it happens in MakeCopyRToNP.
// if(checkRForNA(val))
// {
// makeNAForNP(TYPEOF(val), ret);
// return true;
// }
//Default marshalling behavior
switch(TYPEOF(val))
{
case NILSXP:
break;
case CHARSXP:
MakeCopyRToNP(val, inst, funcs, ret);
break;
case REALSXP:
case INTSXP:
case LGLSXP:
case STRSXP:
if(LENGTH(val) <= 1)
MakeCopyRToNP(val, inst, funcs, ret);
else
MakeRRefForNP(val, inst, funcs, ret);
break;
case CLOSXP:
case S4SXP:
case VECSXP:
default:
MakeRRefForNP(val, inst, funcs, ret);
break;
//Default marshalling behavior
canfree = false;
switch(TYPEOF(val))
{
case NILSXP:
break;
case CHARSXP:
MakeCopyRToNP(val, inst, funcs, ret);
canfree = true;
break;
case REALSXP:
case INTSXP:
case LGLSXP:
case STRSXP:
if(LENGTH(val) <= 1)
{
MakeCopyRToNP(val, inst, funcs, ret);
canfree = true;
}
else
MakeRRefForNP(val, inst, funcs, ret);
break;
case CLOSXP:
case S4SXP:
case VECSXP:
default:
MakeRRefForNP(val, inst, funcs, ret);
break;
}
}
if(numprot)
UNPROTECT(1);
return true;
UNPROTECT(numprot);
fprintf(stderr, "Leaving ConvertRToNP\n");fflush(stderr);
return canfree;
}

void MakeCopyRToNP(SEXP val, NPP inst, NPNetscapeFuncs *funcs, NPVariant *ret)
Expand Down Expand Up @@ -716,62 +719,65 @@ void MakeRRefForNP(SEXP obj, NPP inst, NPNetscapeFuncs *funcs, NPVariant *ret)
R_PreserveObject(retobj->object);
OBJECT_TO_NPVARIANT(retobj, *ret);
}
}
switch(TYPEOF(ans))
{
case CLOSXP:
// if (TYPEOF(ans) == CLOSXP)
{
RFunction *retobj;
retobj = (RFunction *) funcs->createobject(inst, &RFunction::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
OBJECT_TO_NPVARIANT(retobj, *ret);
break;
}
case LGLSXP:
case INTSXP:
case REALSXP:
case STRSXP:
{
RVector *retobj;
retobj = (RVector *) funcs->createobject(inst, &RVector::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
//retobj->vecType = TYPEOF(ans);
OBJECT_TO_NPVARIANT(retobj, *ret);

break;
}

case VECSXP:
} else {

switch(TYPEOF(ans))
{
RList *retobj;
retobj = (RList *) funcs->createobject(inst, &RList::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
OBJECT_TO_NPVARIANT(retobj, *ret);
case CLOSXP:
// if (TYPEOF(ans) == CLOSXP)
{
RFunction *retobj;
retobj = (RFunction *) funcs->createobject(inst, &RFunction::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
OBJECT_TO_NPVARIANT(retobj, *ret);
break;
}
case LGLSXP:
case INTSXP:
case REALSXP:
case STRSXP:
{
RVector *retobj;
retobj = (RVector *) funcs->createobject(inst, &RVector::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
//retobj->vecType = TYPEOF(ans);
OBJECT_TO_NPVARIANT(retobj, *ret);

break;
}

break;
}

default:
{
RObject *retobj;
retobj = (RObject *) funcs->createobject(inst, &RObject::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
OBJECT_TO_NPVARIANT(retobj, *ret);
case VECSXP:
{
RList *retobj;
retobj = (RList *) funcs->createobject(inst, &RList::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
OBJECT_TO_NPVARIANT(retobj, *ret);

break;
}

default:
{
RObject *retobj;
retobj = (RObject *) funcs->createobject(inst, &RObject::_npclass);
funcs->retainobject(retobj);
retobj->object = ans;
retobj->funcs = funcs;
R_PreserveObject(retobj->object);
OBJECT_TO_NPVARIANT(retobj, *ret);
}
}
}
}
return;
}

Expand Down
12 changes: 12 additions & 0 deletions inst/NPAPI/WebR.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,39 @@
#include "npapi.h"
#include "npfunctions.h"
#include <npruntime.h>
extern "C" {
#include <stdio.h>
}
//#include "pthread.h"

#define USE_R_INTERNALS 1


#ifndef _WIN32
#define CSTACK_DEFNS 1
#endif

#ifndef XP_MACOSX
extern "C" {
#include <R.h>
#include <Rdefines.h>
#include <Rembedded.h>
}
#ifdef XP_UNIX
extern "C" {
#include <Rinterface.h>
#include <Rinternals.h>
}
#endif
#else
extern "C" {
#include <R/R.h>
#include <R/Rdefines.h>
#include <R/Rembedded.h>
#include <R/Rinterface.h>
#include <R/Rinternals.h>
}

#endif

typedef enum convert_behavior {
Expand Down
12 changes: 6 additions & 6 deletions inst/NPAPI/WebREngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,26 +257,26 @@ bool WebREngine::HasProperty(NPIdentifier name)

bool WebREngine::GetProperty(NPIdentifier name, NPVariant *result)
{
bool ret;
bool ret = true;
if(name == myNPNFuncs->getstringidentifier("serving"))
{
INT32_TO_NPVARIANT(rQueue.serving, *result);
ret = 1;
}
}
else
{

fprintf(stderr, "\nIn WebREngine::GetProperty");fflush(stderr);
SEXP val;
PROTECT(val = doGetVar(name, this->instance));

if(val == R_UnboundValue)
ret = false;


if(TYPEOF(val) == CLOSXP)
ret = ConvertRToNP(val, this->instance, myNPNFuncs, result, CONV_DEFAULT);
ConvertRToNP(val, this->instance, myNPNFuncs, result, CONV_DEFAULT);
else

ret = ConvertRToNP(val, this->instance, myNPNFuncs, result, CONV_DEFAULT) ;
ConvertRToNP(val, this->instance, myNPNFuncs, result, CONV_DEFAULT) ;
UNPROTECT(1);
}
return ret;
Expand Down
2 changes: 1 addition & 1 deletion inst/NPAPI/WebRObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ bool RSubsettableObject::HasProperty(NPIdentifier name)
if(this->funcs->identifierisstring(name))
SETCAR(ptr, ScalarString(mkChar(this->funcs->utf8fromidentifier(name))));
else
SETCAR(ptr, ScalarInteger(this->funcs->intfromidentifier(name)));
SETCAR(ptr, ScalarInteger(this->funcs->intfromidentifier(name)+1)); //+1 because JS indexing starts at 0, but R indexing starts at 1
PROTECT(ans = rQueue.requestRCall(call, R_GlobalEnv, &error, this->instance));

if(!error)
Expand Down
2 changes: 1 addition & 1 deletion inst/NPAPI/jsStartup.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
#define JS_INIT_H 1
//static const char *JS_INIT_CODE = "function runScriptsNPAPI(){var e=window.document.getElementsByTagName('embed');var t=window.document.getElementsByTagName('script');var n;for(var r=0;r<e.length;r++){if(e[r].type=='application/r'){n=e[r];break}}if(typeof n=='undefined')return;var i;var s;var o;for(var u=0;u<t.length;u++){i=t[u];if(i.type=='text/R'){o=n.eval(i.text);if(i.src)o=n.source(i.src)}}window.R=n;var a=document.createEvent('Events');a.initEvent('rcoderun',true,false);document.dispatchEvent(a)}function namedArgsCall(e,t){R[e](args(t))}function makeFun(e){function t(){var t=Array.prototype.slice.call(arguments);window.R.listCall(e,t)}return t}function args(e){e.namedArgsForR=true;if(typeof e.convertRet=='undefined'||e.convertRet=='default'||e.convertRet==1)e.convertRet=1;else if(e.convertRet=='reference'||e.convertRet==0)e.convertRet=0;else if(e.convertRet=='copy'||e.convertRet==2)e.convertRet=2;else if((e.convertRet=='custom'||e.convertRet==3)&&e.convertFun!='undefined')e.convertRet=3;else throw'Unrecognized value for convertRet argument:'+e.convertRet;return e}function create0(e){var t=new e;return t}function create1(e,t){var n=new e(t);return n}function create2(e,t,n){var r=new e(t,n);return r}function create3(e,t,n,r){var i=new e(t,n,r);return i}function create4(e,t,n,r,i){var s=new e(t,n,r,i);return s}window.emptyArg={emptyRArg:true};runScriptsNPAPI();//setTimeout(runScriptsNPAPI,200)";

static const char *JS_INIT_CODE = "function runScriptsNPAPI(){var e=window.document.getElementsByTagName('embed');var t=window.document.getElementsByTagName('script');var n;for(var r=0;r<e.length;r++){if(e[r].type=='application/test-r'||e[r].type=='application/r'){n=e[r];break}}if(typeof n=='undefined')return;var i;var s;var o;for(var u=0;u<t.length;u++){i=t[u];if(i.type=='text/R'){o=n.eval(i.text);if(i.src)o=n.source(i.src)}}window.R=n;var a=document.createEvent('Events');a.initEvent('rcoderun',true,false);document.dispatchEvent(a)}function namedArgsCall(e,t){R[e](args(t))}function makeFun(e){function t(){var t=Array.prototype.slice.call(arguments);window.R.listCall(e,t)}return t}function args(e){e.namedArgsForR=true;if(typeof e.convertRet=='undefined'||e.convertRet=='default'||e.convertRet==1)e.convertRet=1;else if(e.convertRet=='reference'||e.convertRet==0)e.convertRet=0;else if(e.convertRet=='copy'||e.convertRet==2)e.convertRet=2;else if((e.convertRet=='custom'||e.convertRet==3)&&e.convertFun!='undefined')e.convertRet=3;else throw'Unrecognized value for convertRet argument:'+e.convertRet;return e}function create0(e){var t=new e;return t}function create1(e,t){var n=new e(t);return n}function create2(e,t,n){var r=new e(t,n);return r}function create3(e,t,n,r){var i=new e(t,n,r);return i}function create4(e,t,n,r,i){var s=new e(t,n,r,i);return s}window.emptyArg={emptyRArg:true};setTimeout(runScriptsNPAPI,200)";
static const char *JS_INIT_CODE = "function runScriptsNPAPI(){var e=window.document.getElementsByTagName('embed');var t=window.document.getElementsByTagName('script');var n;for(var r=0;r<e.length;r++){if(e[r].type=='application/test-r'||e[r].type=='application/r'){n=e[r];break}}if(typeof n=='undefined')return;var i;var s;var o;for(var u=0;u<t.length;u++){i=t[u];if(i.type=='text/R'){o=n.eval(i.text);if(i.src)o=n.source(i.src)}}window.R=n;var a=document.createEvent('Events');a.initEvent('rcoderun',true,false);document.dispatchEvent(a)}function namedArgsCall(e,t){R[e](args(t))}function makeFun(e){function t(){var t=Array.prototype.slice.call(arguments);window.R.listCall(e,t)}return t}function args(e){e.namedArgsForR=true;if(typeof e.convertRet=='undefined'||e.convertRet=='default'||e.convertRet==0)e.convertRet=0;else if(e.convertRet=='reference'||e.convertRet==1)e.convertRet=1;else if(e.convertRet=='copy'||e.convertRet==2)e.convertRet=2;else if((e.convertRet=='custom'||e.convertRet==3)&&e.convertFun!='undefined')e.convertRet=3;else throw'Unrecognized value for convertRet argument:'+e.convertRet;return e}function create0(e){var t=new e;return t}function create1(e,t){var n=new e(t);return n}function create2(e,t,n){var r=new e(t,n);return r}function create3(e,t,n,r){var i=new e(t,n,r);return i}function create4(e,t,n,r,i){var s=new e(t,n,r,i);return s}window.emptyArg={emptyRArg:true};setTimeout(runScriptsNPAPI,200)";
#endif //JS_INIT_CODE
Loading

0 comments on commit 732f473

Please sign in to comment.