mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-24 04:54:40 +02:00
8020731: Revisit checkPermission calls in Context class
Reviewed-by: attila, hannesw
This commit is contained in:
parent
c4bea48ac1
commit
21be9aded6
10 changed files with 73 additions and 229 deletions
|
@ -209,10 +209,10 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
}
|
||||
|
||||
try {
|
||||
final ScriptObject oldGlobal = getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
try {
|
||||
if(oldGlobal != ctxtGlobal) {
|
||||
setNashornGlobal(ctxtGlobal);
|
||||
Context.setGlobal(ctxtGlobal);
|
||||
}
|
||||
|
||||
if (! isInterfaceImplemented(clazz, realSelf)) {
|
||||
|
@ -221,7 +221,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf));
|
||||
} finally {
|
||||
if(oldGlobal != ctxtGlobal) {
|
||||
setNashornGlobal(oldGlobal);
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
} catch(final RuntimeException|Error e) {
|
||||
|
@ -357,7 +357,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
}
|
||||
|
||||
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
|
||||
final ScriptObject oldGlobal = getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
|
||||
final boolean globalChanged = (oldGlobal != ctxtGlobal);
|
||||
|
||||
|
@ -365,7 +365,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
|
||||
try {
|
||||
if (globalChanged) {
|
||||
setNashornGlobal(ctxtGlobal);
|
||||
Context.setGlobal(ctxtGlobal);
|
||||
}
|
||||
|
||||
ScriptObject sobj;
|
||||
|
@ -398,7 +398,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
throw new NoSuchMethodException(name);
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
setNashornGlobal(oldGlobal);
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -411,12 +411,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
if (script == null) {
|
||||
return null;
|
||||
}
|
||||
final ScriptObject oldGlobal = getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
|
||||
final boolean globalChanged = (oldGlobal != ctxtGlobal);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
setNashornGlobal(ctxtGlobal);
|
||||
Context.setGlobal(ctxtGlobal);
|
||||
}
|
||||
|
||||
setContextVariables(ctxt);
|
||||
|
@ -426,7 +426,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
throw new AssertionError("should not reach here");
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
setNashornGlobal(oldGlobal);
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,12 +469,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
}
|
||||
|
||||
private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException {
|
||||
final ScriptObject oldGlobal = getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
|
||||
final boolean globalChanged = (oldGlobal != ctxtGlobal);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
setNashornGlobal(ctxtGlobal);
|
||||
Context.setGlobal(ctxtGlobal);
|
||||
}
|
||||
|
||||
return nashornContext.compileScript(source, ctxtGlobal);
|
||||
|
@ -483,7 +483,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
throw new AssertionError("should not reach here");
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
setNashornGlobal(oldGlobal);
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -502,19 +502,4 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't make this public!!
|
||||
static ScriptObject getNashornGlobal() {
|
||||
return Context.getGlobal();
|
||||
}
|
||||
|
||||
static void setNashornGlobal(final ScriptObject newGlobal) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
Context.setGlobal(newGlobal);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,12 +79,12 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
// JSObject methods
|
||||
@Override
|
||||
public Object call(final String functionName, final Object... args) {
|
||||
final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final boolean globalChanged = (oldGlobal != global);
|
||||
|
||||
try {
|
||||
if (globalChanged) {
|
||||
NashornScriptEngine.setNashornGlobal(global);
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
|
||||
final Object val = functionName == null? sobj : sobj.get(functionName);
|
||||
|
@ -100,19 +100,19 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
throw new RuntimeException(t);
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
NashornScriptEngine.setNashornGlobal(oldGlobal);
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object newObject(final String functionName, final Object... args) {
|
||||
final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final boolean globalChanged = (oldGlobal != global);
|
||||
|
||||
try {
|
||||
if (globalChanged) {
|
||||
NashornScriptEngine.setNashornGlobal(global);
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
|
||||
final Object val = functionName == null? sobj : sobj.get(functionName);
|
||||
|
@ -128,7 +128,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
throw new RuntimeException(t);
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
NashornScriptEngine.setNashornGlobal(oldGlobal);
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
|
||||
@Override
|
||||
public Object put(final String key, final Object value) {
|
||||
final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final boolean globalChanged = (oldGlobal != global);
|
||||
return inGlobal(new Callable<Object>() {
|
||||
@Override public Object call() {
|
||||
|
@ -284,7 +284,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
|
||||
@Override
|
||||
public void putAll(final Map<? extends String, ? extends Object> map) {
|
||||
final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final boolean globalChanged = (oldGlobal != global);
|
||||
inGlobal(new Callable<Object>() {
|
||||
@Override public Object call() {
|
||||
|
@ -535,7 +535,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
* @return wrapped object
|
||||
*/
|
||||
public static Object wrap(final Object obj, final ScriptObject homeGlobal) {
|
||||
return (obj instanceof ScriptObject) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
|
||||
return (obj instanceof ScriptObject && homeGlobal != null) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -613,10 +613,10 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
|
||||
// internals only below this.
|
||||
private <V> V inGlobal(final Callable<V> callable) {
|
||||
final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
|
||||
final ScriptObject oldGlobal = Context.getGlobal();
|
||||
final boolean globalChanged = (oldGlobal != global);
|
||||
if (globalChanged) {
|
||||
NashornScriptEngine.setNashornGlobal(global);
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
try {
|
||||
return callable.call();
|
||||
|
@ -626,7 +626,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
|
|||
throw new AssertionError("Cannot happen", e);
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
NashornScriptEngine.setNashornGlobal(oldGlobal);
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -411,18 +411,33 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
|||
// initialized by nasgen
|
||||
private static PropertyMap $nasgenmap$;
|
||||
|
||||
// performs initialization checks for Global constructor and returns the
|
||||
// PropertyMap, if everything is fine.
|
||||
private static PropertyMap checkAndGetMap(final Context context) {
|
||||
// security check first
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new RuntimePermission("nashorn.newGlobal"));
|
||||
}
|
||||
|
||||
// null check on context
|
||||
context.getClass();
|
||||
|
||||
/*
|
||||
* Duplicate global's map and use it. This way the initial Map filled
|
||||
* by nasgen (referenced from static field in this class) is retained
|
||||
* 'as is' (as that one is process wide singleton.
|
||||
*/
|
||||
return $nasgenmap$.duplicate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
public Global(final Context context) {
|
||||
/*
|
||||
* Duplicate global's map and use it. This way the initial Map filled
|
||||
* by nasgen (referenced from static field in this class) is retained
|
||||
* 'as is' (as that one is process wide singleton.
|
||||
*/
|
||||
super($nasgenmap$.duplicate());
|
||||
super(checkAndGetMap(context));
|
||||
this.setContext(context);
|
||||
this.setIsScope();
|
||||
|
||||
|
|
|
@ -121,11 +121,6 @@ public final class Context {
|
|||
* @param global the global scope
|
||||
*/
|
||||
public static void setGlobal(final ScriptObject global) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new RuntimePermission("nashorn.setGlobal"));
|
||||
}
|
||||
|
||||
if (global != null && !(global instanceof Global)) {
|
||||
throw new IllegalArgumentException("global is not an instance of Global!");
|
||||
}
|
||||
|
@ -645,12 +640,7 @@ public final class Context {
|
|||
* @return the global script object
|
||||
*/
|
||||
public ScriptObject newGlobal() {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new RuntimePermission("nashorn.newGlobal"));
|
||||
}
|
||||
|
||||
return newGlobalTrusted();
|
||||
return new Global(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -828,10 +818,6 @@ public final class Context {
|
|||
});
|
||||
}
|
||||
|
||||
private ScriptObject newGlobalTrusted() {
|
||||
return new Global(this);
|
||||
}
|
||||
|
||||
private long getUniqueScriptId() {
|
||||
return uniqueScriptId.getAndIncrement();
|
||||
}
|
||||
|
|
|
@ -84,8 +84,8 @@ public final class NativeJavaPackage extends ScriptObject {
|
|||
* @param proto proto
|
||||
*/
|
||||
public NativeJavaPackage(final String name, final ScriptObject proto) {
|
||||
super(proto, null);
|
||||
this.name = name;
|
||||
this.setProto(proto);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -335,9 +335,7 @@ public final class ScriptRuntime {
|
|||
*/
|
||||
public static Object checkAndApply(final ScriptFunction target, final Object self, final Object... args) {
|
||||
final ScriptObject global = Context.getGlobalTrusted();
|
||||
if (! (global instanceof GlobalObject)) {
|
||||
throw new IllegalStateException("No current global set");
|
||||
}
|
||||
assert (global instanceof GlobalObject): "No current global set";
|
||||
|
||||
if (target.getContext() != global.getContext()) {
|
||||
throw new IllegalArgumentException("'target' function is not from current Context");
|
||||
|
|
|
@ -58,10 +58,8 @@ public final class WithObject extends ScriptObject implements Scope {
|
|||
* @param expression with expression
|
||||
*/
|
||||
public WithObject(final ScriptObject scope, final Object expression) {
|
||||
super();
|
||||
|
||||
super(scope, null);
|
||||
setIsScope();
|
||||
setProto(scope);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,23 @@ import jdk.nashorn.internal.runtime.ScriptObject;
|
|||
* constructor's trailing position and thus provide further instance-specific overrides. The order of invocation is
|
||||
* always instance-specified method, then a class-specified method, and finally the superclass method.
|
||||
*/
|
||||
final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
|
||||
final class JavaAdapterBytecodeGenerator {
|
||||
static final Type CONTEXT_TYPE = Type.getType(Context.class);
|
||||
static final Type OBJECT_TYPE = Type.getType(Object.class);
|
||||
static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
|
||||
|
||||
static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
|
||||
static final String OBJECT_TYPE_NAME = OBJECT_TYPE.getInternalName();
|
||||
|
||||
static final String INIT = "<init>";
|
||||
|
||||
static final String GLOBAL_FIELD_NAME = "global";
|
||||
|
||||
static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
|
||||
|
||||
static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, SCRIPT_OBJECT_TYPE);
|
||||
static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
|
||||
|
||||
private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
|
||||
private static final Type STRING_TYPE = Type.getType(String.class);
|
||||
private static final Type METHOD_TYPE_TYPE = Type.getType(MethodType.class);
|
||||
|
@ -151,7 +167,7 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
|
|||
// Class name suffix used to append to the adaptee class name, when it can be defined in the adaptee's package.
|
||||
private static final String ADAPTER_CLASS_NAME_SUFFIX = "$$NashornJavaAdapter";
|
||||
private static final String JAVA_PACKAGE_PREFIX = "java/";
|
||||
private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 238; //255 - 17; 17 is the maximum possible length for the global setter inner class suffix
|
||||
private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 255;
|
||||
|
||||
private static final String CLASS_INIT = "<clinit>";
|
||||
private static final String STATIC_GLOBAL_FIELD_NAME = "staticGlobal";
|
||||
|
@ -175,8 +191,6 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
|
|||
private final String superClassName;
|
||||
// Binary name of the generated class.
|
||||
private final String generatedClassName;
|
||||
// Binary name of the PrivilegedAction inner class that is used to
|
||||
private final String globalSetterClassName;
|
||||
private final Set<String> usedFieldNames = new HashSet<>();
|
||||
private final Set<String> abstractMethodNames = new HashSet<>();
|
||||
private final String samName;
|
||||
|
@ -220,9 +234,6 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
|
|||
l = random.nextLong();
|
||||
}
|
||||
|
||||
// NOTE: they way this class name is calculated affects the value of MAX_GENERATED_TYPE_NAME_LENGTH constant. If
|
||||
// you change the calculation of globalSetterClassName, adjust the constant too.
|
||||
globalSetterClassName = generatedClassName.concat("$" + Long.toHexString(l & Long.MAX_VALUE));
|
||||
cw.visit(Opcodes.V1_7, ACC_PUBLIC | ACC_SUPER | ACC_FINAL, generatedClassName, null, superClassName, getInternalTypeNames(interfaces));
|
||||
|
||||
generateGlobalFields();
|
||||
|
@ -250,7 +261,7 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
|
|||
}
|
||||
|
||||
JavaAdapterClassLoader createAdapterClassLoader() {
|
||||
return new JavaAdapterClassLoader(generatedClassName, cw.toByteArray(), globalSetterClassName);
|
||||
return new JavaAdapterClassLoader(generatedClassName, cw.toByteArray());
|
||||
}
|
||||
|
||||
boolean isAutoConvertibleFromFunction() {
|
||||
|
@ -511,8 +522,8 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
|
|||
mv.invokestatic(CONTEXT_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR);
|
||||
}
|
||||
|
||||
private void invokeSetGlobal(final InstructionAdapter mv) {
|
||||
mv.invokestatic(globalSetterClassName, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR);
|
||||
private static void invokeSetGlobal(final InstructionAdapter mv) {
|
||||
mv.invokestatic(CONTEXT_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -794,7 +805,7 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
|
|||
* entry.
|
||||
* @param globalsDifferVar index of the boolean local variable that is true if the global needs to be restored.
|
||||
*/
|
||||
private void emitFinally(final InstructionAdapter mv, final int currentGlobalVar, final int globalsDifferVar) {
|
||||
private static void emitFinally(final InstructionAdapter mv, final int currentGlobalVar, final int globalsDifferVar) {
|
||||
// Emit code to restore the previous Nashorn global if needed
|
||||
mv.visitVarInsn(ILOAD, globalsDifferVar);
|
||||
final Label skip = new Label();
|
||||
|
|
|
@ -25,16 +25,6 @@
|
|||
|
||||
package jdk.nashorn.internal.runtime.linker;
|
||||
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.AllPermission;
|
||||
import java.security.CodeSigner;
|
||||
|
@ -45,12 +35,6 @@ import java.security.ProtectionDomain;
|
|||
import java.security.SecureClassLoader;
|
||||
|
||||
import jdk.internal.dynalink.beans.StaticClass;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
|
||||
/**
|
||||
* This class encapsulates the bytecode of the adapter class and can be used to load it into the JVM as an actual Class.
|
||||
|
@ -60,22 +44,15 @@ import jdk.nashorn.internal.runtime.ScriptObject;
|
|||
* class are normally created by {@link JavaAdapterBytecodeGenerator}.
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
class JavaAdapterClassLoader extends JavaAdapterGeneratorBase {
|
||||
private static final Type PRIVILEGED_ACTION_TYPE = Type.getType(PrivilegedAction.class);
|
||||
|
||||
private static final String PRIVILEGED_ACTION_TYPE_NAME = PRIVILEGED_ACTION_TYPE.getInternalName();
|
||||
private static final String PRIVILEGED_RUN_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE);
|
||||
|
||||
final class JavaAdapterClassLoader {
|
||||
private static final ProtectionDomain GENERATED_PROTECTION_DOMAIN = createGeneratedProtectionDomain();
|
||||
|
||||
private final String className;
|
||||
private final byte[] classBytes;
|
||||
private final String globalSetterClassName;
|
||||
|
||||
JavaAdapterClassLoader(String className, byte[] classBytes, String globalSetterClassName) {
|
||||
JavaAdapterClassLoader(String className, byte[] classBytes) {
|
||||
this.className = className.replace('/', '.');
|
||||
this.classBytes = classBytes;
|
||||
this.globalSetterClassName = globalSetterClassName.replace('/', '.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +93,6 @@ class JavaAdapterClassLoader extends JavaAdapterGeneratorBase {
|
|||
private ClassLoader createClassLoader(final ClassLoader parentLoader) {
|
||||
return new AdapterLoader(parentLoader) {
|
||||
private final ClassLoader myLoader = getClass().getClassLoader();
|
||||
private final ProtectionDomain myProtectionDomain = getClass().getProtectionDomain();
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
|
||||
|
@ -138,9 +114,6 @@ class JavaAdapterClassLoader extends JavaAdapterGeneratorBase {
|
|||
protected Class<?> findClass(final String name) throws ClassNotFoundException {
|
||||
if(name.equals(className)) {
|
||||
return defineClass(name, classBytes, 0, classBytes.length, GENERATED_PROTECTION_DOMAIN);
|
||||
} else if(name.equals(globalSetterClassName)) {
|
||||
final byte[] bytes = generatePrivilegedActionClassBytes(globalSetterClassName.replace('.', '/'));
|
||||
return defineClass(name, bytes, 0, bytes.length, myProtectionDomain);
|
||||
} else {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
@ -158,70 +131,4 @@ class JavaAdapterClassLoader extends JavaAdapterGeneratorBase {
|
|||
permissions.add(new AllPermission());
|
||||
return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PrivilegedAction implementation class for invoking {@link Context#setGlobal(ScriptObject)} from the
|
||||
* adapter class.
|
||||
*/
|
||||
private static byte[] generatePrivilegedActionClassBytes(final String className) {
|
||||
final ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
// class GlobalSetter implements PrivilegedAction {
|
||||
w.visit(Opcodes.V1_7, ACC_SUPER | ACC_FINAL, className, null, OBJECT_TYPE_NAME, new String[] {
|
||||
PRIVILEGED_ACTION_TYPE_NAME
|
||||
});
|
||||
|
||||
// private final ScriptObject global;
|
||||
w.visitField(ACC_PRIVATE | ACC_FINAL, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
|
||||
|
||||
// private GlobalSetter(ScriptObject global) {
|
||||
InstructionAdapter mv = new InstructionAdapter(w.visitMethod(ACC_PRIVATE, INIT,
|
||||
SET_GLOBAL_METHOD_DESCRIPTOR, null, new String[0]));
|
||||
mv.visitCode();
|
||||
// super();
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.invokespecial(OBJECT_TYPE_NAME, INIT, VOID_NOARG_METHOD_DESCRIPTOR);
|
||||
// this.global = global;
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.putfield(className, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
|
||||
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitEnd();
|
||||
mv.visitMaxs(0, 0);
|
||||
|
||||
// public Object run() {
|
||||
mv = new InstructionAdapter(w.visitMethod(ACC_PUBLIC, "run", PRIVILEGED_RUN_METHOD_DESCRIPTOR, null,
|
||||
new String[0]));
|
||||
mv.visitCode();
|
||||
// Context.setGlobal(this.global);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.getfield(className, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
|
||||
mv.invokestatic(CONTEXT_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR);
|
||||
// return null;
|
||||
mv.visitInsn(ACONST_NULL);
|
||||
mv.visitInsn(ARETURN);
|
||||
|
||||
mv.visitEnd();
|
||||
mv.visitMaxs(0, 0);
|
||||
|
||||
// static void setGlobal(ScriptObject global) {
|
||||
mv = new InstructionAdapter(w.visitMethod(ACC_STATIC, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR, null,
|
||||
new String[0]));
|
||||
mv.visitCode();
|
||||
// new GlobalSetter(ScriptObject global)
|
||||
mv.anew(Type.getType("L" + className + ";"));
|
||||
mv.dup();
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.invokespecial(className, INIT, SET_GLOBAL_METHOD_DESCRIPTOR);
|
||||
// AccessController.doPrivileged(...)
|
||||
mv.invokestatic(Type.getInternalName(AccessController.class), "doPrivileged", Type.getMethodDescriptor(
|
||||
OBJECT_TYPE, PRIVILEGED_ACTION_TYPE));
|
||||
mv.pop();
|
||||
mv.visitInsn(RETURN);
|
||||
|
||||
mv.visitEnd();
|
||||
mv.visitMaxs(0, 0);
|
||||
|
||||
return w.toByteArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.runtime.linker;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
|
||||
/**
|
||||
* Base class for both {@link JavaAdapterBytecodeGenerator} and {@link JavaAdapterClassLoader}, containing those
|
||||
* bytecode types, type names and method descriptor that are used by both.
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
abstract class JavaAdapterGeneratorBase {
|
||||
static final Type CONTEXT_TYPE = Type.getType(Context.class);
|
||||
static final Type OBJECT_TYPE = Type.getType(Object.class);
|
||||
static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
|
||||
|
||||
static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
|
||||
static final String OBJECT_TYPE_NAME = OBJECT_TYPE.getInternalName();
|
||||
|
||||
static final String INIT = "<init>";
|
||||
|
||||
static final String GLOBAL_FIELD_NAME = "global";
|
||||
|
||||
static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
|
||||
|
||||
static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, SCRIPT_OBJECT_TYPE);
|
||||
static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
|
||||
|
||||
protected JavaAdapterGeneratorBase() {
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue