001: /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002: *
003: * ***** BEGIN LICENSE BLOCK *****
004: * Version: MPL 1.1/GPL 2.0
005: *
006: * The contents of this file are subject to the Mozilla Public License Version
007: * 1.1 (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: * http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the
014: * License.
015: *
016: * The Original Code is Rhino code, released
017: * May 6, 1999.
018: *
019: * The Initial Developer of the Original Code is
020: * Netscape Communications Corporation.
021: * Portions created by the Initial Developer are Copyright (C) 1997-2000
022: * the Initial Developer. All Rights Reserved.
023: *
024: * Contributor(s):
025: *
026: * Alternatively, the contents of this file may be used under the terms of
027: * the GNU General Public License Version 2 or later (the "GPL"), in which
028: * case the provisions of the GPL are applicable instead of those above. If
029: * you wish to allow use of your version of this file only under the terms of
030: * the GPL and not to allow others to use your version of this file under the
031: * MPL, indicate your decision by deleting the provisions above and replacing
032: * them with the notice and other provisions required by the GPL. If you do
033: * not delete the provisions above, a recipient may use your version of this
034: * file under either the MPL or the GPL.
035: *
036: * ***** END LICENSE BLOCK ***** */
037:
038: package org.mozilla.javascript.jdk13;
039:
040: import java.lang.reflect.AccessibleObject;
041: import java.lang.reflect.Constructor;
042: import java.lang.reflect.InvocationHandler;
043: import java.lang.reflect.InvocationTargetException;
044: import java.lang.reflect.Method;
045: import java.lang.reflect.Member;
046: import java.lang.reflect.Proxy;
047:
048: import org.mozilla.javascript.*;
049:
050: public class VMBridge_jdk13 extends VMBridge {
051: private ThreadLocal contextLocal = new ThreadLocal();
052:
053: protected Object getThreadContextHelper() {
054: // To make subsequent batch calls to getContext/setContext faster
055: // associate permanently one element array with contextLocal
056: // so getContext/setContext would need just to read/write the first
057: // array element.
058: // Note that it is necessary to use Object[], not Context[] to allow
059: // garbage collection of Rhino classes. For details see comments
060: // by Attila Szegedi in
061: // https://bugzilla.mozilla.org/show_bug.cgi?id=281067#c5
062:
063: Object[] storage = (Object[]) contextLocal.get();
064: if (storage == null) {
065: storage = new Object[1];
066: contextLocal.set(storage);
067: }
068: return storage;
069: }
070:
071: protected Context getContext(Object contextHelper) {
072: Object[] storage = (Object[]) contextHelper;
073: return (Context) storage[0];
074: }
075:
076: protected void setContext(Object contextHelper, Context cx) {
077: Object[] storage = (Object[]) contextHelper;
078: storage[0] = cx;
079: }
080:
081: protected ClassLoader getCurrentThreadClassLoader() {
082: return Thread.currentThread().getContextClassLoader();
083: }
084:
085: protected boolean tryToMakeAccessible(Object accessibleObject) {
086: if (!(accessibleObject instanceof AccessibleObject)) {
087: return false;
088: }
089: AccessibleObject accessible = (AccessibleObject) accessibleObject;
090: if (accessible.isAccessible()) {
091: return true;
092: }
093: try {
094: accessible.setAccessible(true);
095: } catch (Exception ex) {
096: }
097:
098: return accessible.isAccessible();
099: }
100:
101: protected Object getInterfaceProxyHelper(ContextFactory cf,
102: Class[] interfaces) {
103: // XXX: How to handle interfaces array withclasses from different
104: // class loaders? Using cf.getApplicationClassLoader() ?
105: ClassLoader loader = interfaces[0].getClassLoader();
106: Class cl = Proxy.getProxyClass(loader, interfaces);
107: Constructor c;
108: try {
109: c = cl
110: .getConstructor(new Class[] { InvocationHandler.class });
111: } catch (NoSuchMethodException ex) {
112: // Should not happen
113: throw Kit.initCause(new IllegalStateException(), ex);
114: }
115: return c;
116: }
117:
118: protected Object newInterfaceProxy(Object proxyHelper,
119: final ContextFactory cf, final InterfaceAdapter adapter,
120: final Object target, final Scriptable topScope) {
121: Constructor c = (Constructor) proxyHelper;
122:
123: InvocationHandler handler = new InvocationHandler() {
124: public Object invoke(Object proxy, Method method,
125: Object[] args) {
126: return adapter.invoke(cf, target, topScope, method,
127: args);
128: }
129: };
130: Object proxy;
131: try {
132: proxy = c.newInstance(new Object[] { handler });
133: } catch (InvocationTargetException ex) {
134: throw Context.throwAsScriptRuntimeEx(ex);
135: } catch (IllegalAccessException ex) {
136: // Shouls not happen
137: throw Kit.initCause(new IllegalStateException(), ex);
138: } catch (InstantiationException ex) {
139: // Shouls not happen
140: throw Kit.initCause(new IllegalStateException(), ex);
141: }
142: return proxy;
143: }
144:
145: protected boolean isVarArgs(Member member) {
146: return false;
147: }
148: }
|