13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.runtime.linker; 27 28 import java.lang.invoke.MethodHandle; 29 import java.lang.invoke.MethodHandles; 30 import java.lang.invoke.MethodType; 31 import java.util.HashMap; 32 import java.util.Map; 33 import jdk.internal.dynalink.CallSiteDescriptor; 34 import jdk.internal.dynalink.linker.GuardedInvocation; 35 import jdk.internal.dynalink.linker.GuardedTypeConversion; 36 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; 37 import jdk.internal.dynalink.linker.LinkRequest; 38 import jdk.internal.dynalink.linker.LinkerServices; 39 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 40 import jdk.internal.dynalink.support.CallSiteDescriptorFactory; 41 import jdk.nashorn.api.scripting.JSObject; 42 import jdk.nashorn.internal.lookup.MethodHandleFactory; 43 import jdk.nashorn.internal.lookup.MethodHandleFunctionality; 44 import jdk.nashorn.internal.runtime.JSType; 45 46 /** 47 * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well 48 * as ScriptObjects from other Nashorn contexts. 49 */ 50 final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory { 51 @Override 52 public boolean canLinkType(final Class<?> type) { 53 return canLinkTypeStatic(type); 54 } 55 56 static boolean canLinkTypeStatic(final Class<?> type) { 57 // can link JSObject 58 return JSObject.class.isAssignableFrom(type); 59 } 60 61 @Override 62 public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { 63 final LinkRequest requestWithoutContext = request.withoutRuntimeContext(); // Nashorn has no runtime context 64 final Object self = requestWithoutContext.getReceiver(); 65 final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor(); 66 67 if (desc.getNameTokenCount() < 2 || !"dyn".equals(desc.getNameToken(CallSiteDescriptor.SCHEME))) { 68 // We only support standard "dyn:*[:*]" operations 69 return null; 70 } 71 72 final GuardedInvocation inv; 73 if (self instanceof JSObject) { 74 inv = lookup(desc); 75 } else { 76 throw new AssertionError(); // Should never reach here. 77 } 78 79 return Bootstrap.asType(inv, linkerServices, desc); 80 } 81 82 @Override 83 public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception { 84 final boolean sourceIsAlwaysJSObject = JSObject.class.isAssignableFrom(sourceType); 85 if(!sourceIsAlwaysJSObject && !sourceType.isAssignableFrom(JSObject.class)) { 86 return null; 87 } 88 89 final MethodHandle converter = CONVERTERS.get(targetType); 90 if(converter == null) { 91 return null; 92 } 93 94 return new GuardedTypeConversion(new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType)), true); | 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.runtime.linker; 27 28 import java.lang.invoke.MethodHandle; 29 import java.lang.invoke.MethodHandles; 30 import java.lang.invoke.MethodType; 31 import java.util.HashMap; 32 import java.util.Map; 33 import javax.script.Bindings; 34 import jdk.internal.dynalink.CallSiteDescriptor; 35 import jdk.internal.dynalink.linker.GuardedInvocation; 36 import jdk.internal.dynalink.linker.GuardedTypeConversion; 37 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; 38 import jdk.internal.dynalink.linker.LinkRequest; 39 import jdk.internal.dynalink.linker.LinkerServices; 40 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 41 import jdk.internal.dynalink.support.CallSiteDescriptorFactory; 42 import jdk.nashorn.api.scripting.JSObject; 43 import jdk.nashorn.internal.lookup.MethodHandleFactory; 44 import jdk.nashorn.internal.lookup.MethodHandleFunctionality; 45 import jdk.nashorn.internal.runtime.JSType; 46 47 /** 48 * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well 49 * as ScriptObjects from other Nashorn contexts. 50 */ 51 final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory { 52 private final NashornBeansLinker nashornBeansLinker; 53 54 JSObjectLinker(final NashornBeansLinker nashornBeansLinker) { 55 this.nashornBeansLinker = nashornBeansLinker; 56 } 57 58 @Override 59 public boolean canLinkType(final Class<?> type) { 60 return canLinkTypeStatic(type); 61 } 62 63 static boolean canLinkTypeStatic(final Class<?> type) { 64 // can link JSObject also handles Map, Bindings to make 65 // sure those are not JSObjects. 66 return Map.class.isAssignableFrom(type) || 67 Bindings.class.isAssignableFrom(type) || 68 JSObject.class.isAssignableFrom(type); 69 } 70 71 @Override 72 public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception { 73 final LinkRequest requestWithoutContext = request.withoutRuntimeContext(); // Nashorn has no runtime context 74 final Object self = requestWithoutContext.getReceiver(); 75 final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor(); 76 77 if (desc.getNameTokenCount() < 2 || !"dyn".equals(desc.getNameToken(CallSiteDescriptor.SCHEME))) { 78 // We only support standard "dyn:*[:*]" operations 79 return null; 80 } 81 82 final GuardedInvocation inv; 83 if (self instanceof JSObject) { 84 inv = lookup(desc); 85 } else if (self instanceof Map || self instanceof Bindings) { 86 // guard to make sure the Map or Bindings does not turn into JSObject later! 87 final GuardedInvocation beanInv = nashornBeansLinker.getGuardedInvocation(request, linkerServices); 88 inv = new GuardedInvocation(beanInv.getInvocation(), 89 NashornGuards.combineGuards(beanInv.getGuard(), NashornGuards.getNotJSObjectGuard())); 90 } else { 91 throw new AssertionError(); // Should never reach here. 92 } 93 94 return Bootstrap.asType(inv, linkerServices, desc); 95 } 96 97 @Override 98 public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception { 99 final boolean sourceIsAlwaysJSObject = JSObject.class.isAssignableFrom(sourceType); 100 if(!sourceIsAlwaysJSObject && !sourceType.isAssignableFrom(JSObject.class)) { 101 return null; 102 } 103 104 final MethodHandle converter = CONVERTERS.get(targetType); 105 if(converter == null) { 106 return null; 107 } 108 109 return new GuardedTypeConversion(new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType)), true); |