void marshal_from_sexp<SmokeClassWrapper>(MethodCall *m) { SEXP v = m->sexp(); SmokeType type = m->type(); SmokeObject *o = NULL /*, *coerced = NULL */; /* Not clear if we want to (partially) support this complicated C++ feature if (v != R_NilValue) { o = SmokeObject::fromSexp(v); if (!o->instanceOf(type.className())) { // attempt implicit conversion coerced = o->convertImplicitly(type); if (coerced) o = coerced; else error("Failed to coerce an instance of type '%s' to '%s'", o->className(), type.className()); } } */ o = from_sexp<SmokeObject *>(v, type); void *ptr = o ? o->castPtr(type.className(), m->returning() && !type.fitsStack()) : NULL; setItemValue(m, ptr); /* m->marshal(); if (coerced) delete coerced; */ return; }
/* Clean-up when: (1) Smoke returns something that doesn't fit in StackItem OR (2) Passing arguments to Smoke OR (3) Returning something to Smoke that fits in StackItem. */ inline bool cleanup() const { SmokeType t = type(); return (_mode == RToSmoke && (_cur || (!_cur && t.fitsStack()))) || (!t.fitsStack() && !_cur && _mode == SmokeToR); }