What problem are you ultimately trying to solve?
Assuming that sharing objects between states is something that you need to solve, it seems like a method such as the one you describe could be made to work (notwithstanding any sharp edges that it might introduce) so long as the `fwd` objects are userdatas that could be referenced by two Lua states. That said, I haven't though I haven't thought enough about it to say for sure.
In principle, at the very least, Lua can by made to interface to any library with a C api, including the Lua C API itself. So you one general way to do this would just be to expose the luaL_State pointer for L1 as an opaque userdata in L2 (being careful not to let L2 have access to the actual pointer so as not to contaminate one state with the other at the C level). Then the result might be like this (lua code running in L2):
-- Lua code running in L2.
l2_state = some_c_function_returning_L1_as_userdata()
-- my_object, from L1, is now on the stack.
In other words, you are basically using the Lua C API, via Lua, to operate on L1 using its stack as you would from C. This is a more low-level API then you are proposing, but you could then build a pure Lua library on top of this to expose higher level features (so that you don't have to deal directly with L1's stack). Maybe one down side of this approach is that, when calling L2 code from C/C++, you'd have to specify the relevant L1 object by name, possibly giving it a string-named location in which to find it in L1.
Not saying this approach is better than yours, but it does seem more general. E.g. if you wanted to call L1's `rawget` on one of L1's tables, then you'd have to expose both as `fwd` objects, and those forward objects would have to know how to "unwrap" any `fwd` objects that are given as parameters to a `fwd`d function. Whereas with the approach above, you get automatic access to everything in the L1 state without any wrapping/unwrapping and without any predetermination of what will need to be shared.