The question (as a language / VM designer) is: what do you want?
You can not have a "save language" with "unsafe instructions to write glue code" ... either you are safe or you are unsafe. You could argue: as soon as you can jump into C, you are unsafe anyway. However pure Java would become unsafe, too.
Bottom line your argument writing the "glue code" in Java to be portable is wrong anyway.
The glue code is the thing which makes it possible to interop Java on one side with C/assembly on the other side in a portable way! Usually you only have to recompile the glue code (and link it with the code you want to call).
The problem why you can not write the gluecode in Java portable is very simple: you know nothing about the target architectue where the code will run. You don't know anything about your VM which will execute your code. You know nothing about registers (or do you want to have a VM that has a set of unsafe opcodes for any "thinkable" architecture?) So the VM has to save its own state anyway, regardless of your glue code, before executing it. You know nothing about the calling conventions ... so how do you write glue code that works on a SPARC (using register calling conventions) and works on an x86 (using the stack)? You know nothing about the stack anyway, which register is the stack pointer, oh on x86 this is fix, other processors have more freedom, they can use more than one register as the stack pointer.
Then again: you know noting about the primitive and pointer data types the underlying hardware is using, so how do you write gluecode in a portable way that passes e.g. a "C long" from Java to C? Oh ... in Java a long is 64 bit. Many Cs have a long as 32 bit. Other Cs use "long long" for a 64bit "int" and again some Cs make "short" == "int" == "long". All this are reasons to make the glue code in C. And all this is supported by the JNI "header files" and glue code generators.
Because there we have "typedefs" or more precisely "#defines" for "portable" transfer and conversion of Java primitives into the correct C data types for the platform you are compiling the C code on!
Hint: JNI is a STANDARD, an API! Every JVM implementor who wants to use the trademark Java(tm) has to implement the JVM side of this API in order to be able to use the Sun provided JNI header files and stub code generators. Microsoft stumbled over that with their JVM that did not implement JNI.
The point of JNI is: if I have the gluecode (in C), then I only need to recompile the gluecode on/for the target platform once. Regardless of VM (vendor, word size, OS) and any VM on this platform will be able to access my native code. Granted: it is a bit cumbersome the first time you work with JNI, but later when you have shot yourself often enough into the foot, you realize how smart the inventors/designers in fact where.