I'm not 100% sure I understand the question, but I think the answer is this: all argument passing from one verb to another is, effectively, pass by value. Only MOO Objects get passed by reference. And they have a robust permission structure (which I hope I've implemented right).
So, in the core Java code, all transient values are represented by specific classes. With MOOValue being the base class, and then having MOOString, MOONumber, MOOObjRef, MOOList, and MOOMap being derived classes. The API classes (com.tsatsatzu.moo.core.api) are all written in terms of these classes. For example in MOOObjectAPI: public static MOOObjRef create(MOOObjRef parentRef, MOOObjRef owner) throws MOOException.
For the Javascript driver, these functions are wrapped for the Javascript engine, and do translations between the internal representations and the Javascript representations. So the wrapper for the create() function (FuncObjectAPI) looks like this:
public static Object create(Object arg0, Object arg1) throws MOOException
{
MOOObjRef parent = CoerceLogic.toObjRef(arg0);
MOOObjRef owner = CoerceLogic.toObjRef(arg1);
MOOObjRef ret = MOOObjectAPI.create(parent, owner);
return CoerceLogic.toJavascript(ret);
}
The entities coming in from Javascript are viewed as vanilla Objects in Java. These are then "coerced" into the internal object types we expect for that functional call by common logic. The internal API is called, and, if needed, the reply, which is an internal object type is coerced back to a Javascript object.
So, at least for API calls, a Javascript object would be coerced into a MOOMap and any receiving function would see it as that. They might update it, but unless they return it, those updates will be to a copy.
Thinking on it, though, direct calls to an object (e.g. #0.wibble()) are handled differently. MOOObjRef's are converted to JSObjRef, which have nifty intrinsic methods that make property lookup and assignment work. For verbs, though, they return a JSVerb wrapper around the MOOVerb object which has similarly nifty intrinsic methods that make implicit verb calls work. Looking at the code for that, the objects that come in are just blindly passed down, they are not coerced. So you could have a function call like #0.wibble({"a":"b"}), and with code for wibble that does var wobble = args[0] to get that value.
I have to say I didn't think of that scenario. I don't even know if it works, since you would end up passing an object from one script engine to another script engine. If it does then, yet, that could be a security problem. The called function could modify the object passed to it in arbitrary ways. I may need to put in a layer of coercion in that sort of object to object call. That would force everything down to pass-by-value and limit it to only canonical types.
I should probably write a unit test to replicate that scenario. (Created issue #8.) Good catch.
Jo