@Nullable private MetaMethod findPropertyMissingMethod(MetaClass metaClass) { if (metaClass instanceof MetaClassImpl) { // Reach into meta class to avoid lookup try { return (MetaMethod) MISSING_PROPERTY_GET_METHOD.get(metaClass); } catch (IllegalAccessException e) { throw UncheckedException.throwAsUncheckedException(e); } } // Query the declared methods of the meta class for (MetaMethod method : metaClass.getMethods()) { if (method.getName().equals("propertyMissing") && method.getParameterTypes().length == 1) { return method; } } return null; }
private CallSite createPojoMetaClassGetPropertySite(Object receiver) { final MetaClass metaClass = InvokerHelper.getMetaClass(receiver); CallSite site; if (metaClass.getClass() != MetaClassImpl.class || GroovyCategorySupport.hasCategoryInCurrentThread()) { site = new PojoMetaClassGetPropertySite(this); } else { final MetaProperty effective = ((MetaClassImpl) metaClass).getEffectiveGetMetaProperty(receiver.getClass(), receiver, name, false); if (effective != null) { if (effective instanceof CachedField) site = new GetEffectivePojoFieldSite(this, (MetaClassImpl) metaClass, (CachedField) effective); else site = new GetEffectivePojoPropertySite(this, (MetaClassImpl) metaClass, effective); } else { site = new PojoMetaClassGetPropertySite(this); } } array.array[index] = site; return site; }
private CallSite createPogoMetaClassGetPropertySite(GroovyObject receiver) { MetaClass metaClass = receiver.getMetaClass(); CallSite site; if (metaClass.getClass() != MetaClassImpl.class || GroovyCategorySupport.hasCategoryInCurrentThread()) { site = new PogoMetaClassGetPropertySite(this, metaClass); } else { final MetaProperty effective = ((MetaClassImpl) metaClass).getEffectiveGetMetaProperty(this.array.owner, receiver, name, false); if (effective != null) { if (effective instanceof CachedField) site = new GetEffectivePogoFieldSite(this, metaClass, (CachedField) effective); else site = new GetEffectivePogoPropertySite(this, metaClass, effective); } else { site = new PogoMetaClassGetPropertySite(this, metaClass); } } array.array[index] = site; return site; }
private static CallSite createCallStaticSite(CallSite callSite, final Class receiver, Object[] args) { CallSite site; AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { try { Class.forName(receiver.getName(), true, receiver.getClassLoader()); } catch (Exception e) { // force <clinit> } return null; } }); MetaClass metaClass = InvokerHelper.getMetaClass(receiver); if (metaClass instanceof MetaClassImpl) { site = ((MetaClassImpl)metaClass).createStaticSite(callSite, args); } else site = new StaticMetaClassSite(callSite, metaClass); replaceCallSite(callSite, site); return site; }
private static MetaClass hasPerInstanceMetaClass(Object object) { if (object instanceof GroovyObject) { MetaClass mc = ((GroovyObject)object).getMetaClass(); if (mc == GroovySystem.getMetaClassRegistry().getMetaClass(object.getClass()) || mc.getClass() == MetaClassImpl.class) return null; else return mc; } else { ClassInfo info = ClassInfo.getClassInfo(object.getClass()); info.lock(); try { return info.getPerInstanceMetaClass(object); } finally { info.unlock(); } } }
/** * setting a call site target consists of the following steps: * # get the meta class * # select a method/constructor/property from it, if it is a MetaClassImpl * # make a handle out of the selection * # if nothing could be selected select a path through the given MetaClass or the GroovyObject * # apply transformations for vargs, implicit null argument, coercion, wrapping, null receiver and spreading */ @Override public void setCallSiteTarget() { if (!setNullForSafeNavigation() && !setInterceptor()) { getMetaClass(); if (LOG_ENABLED) LOG.info("meta class is "+mc); setSelectionBase(); MetaClassImpl mci = getMetaClassImpl(mc, callType != CALL_TYPES.GET); chooseMeta(mci); setHandleForMetaMethod(); setMetaClassCallHandleIfNedded(mci!=null); correctParameterLength(); correctCoerce(); correctWrapping(); correctNullReceiver(); correctSpreading(); if (LOG_ENABLED) LOG.info("casting explicit from "+handle.type()+" to "+targetType); handle = MethodHandles.explicitCastArguments(handle,targetType); addExceptionHandler(); } setGuards(args[0]); doCallSiteTargetSet(); }
@Nullable protected MetaProperty lookupProperty(MetaClass metaClass, String name) { if (metaClass instanceof MetaClassImpl) { // MetaClass.getMetaProperty(name) is very expensive when the property is not known. Instead, reach into the meta class to call a much more efficient lookup method try { return (MetaProperty) META_PROP_METHOD.invoke(metaClass, name, false); } catch (Throwable e) { throw UncheckedException.throwAsUncheckedException(e); } } // Some other meta-class implementation - fall back to the public API return metaClass.getMetaProperty(name); }
public void addNewMopMethods(List<MetaMethod> arr) { final MetaClass metaClass = classInfo.getStrongMetaClass(); if (metaClass != null) { if (metaClass.getClass() == MetaClassImpl.class) { classInfo.setStrongMetaClass(null); List<MetaMethod> res = new ArrayList<MetaMethod>(); Collections.addAll(res, classInfo.newMetaMethods); res.addAll(arr); updateSetNewMopMethods(res); MetaClassImpl answer = new MetaClassImpl(((MetaClassImpl)metaClass).getRegistry(),metaClass.getTheClass()); answer.initialize(); classInfo.setStrongMetaClass(answer); return; } if (metaClass.getClass() == ExpandoMetaClass.class) { ExpandoMetaClass emc = (ExpandoMetaClass)metaClass; classInfo.setStrongMetaClass(null); updateAddNewMopMethods(arr); ExpandoMetaClass newEmc = new ExpandoMetaClass(metaClass.getTheClass()); for (MetaMethod mm : emc.getExpandoMethods()) { newEmc.registerInstanceMethod(mm); } newEmc.initialize(); classInfo.setStrongMetaClass(newEmc); return; } throw new GroovyRuntimeException("Can't add methods to class " + getTheClass().getName() + ". Strong custom meta class already set."); } classInfo.setWeakMetaClass(null); updateAddNewMopMethods(arr); }
public static CallSite createPojoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { if (metaMethod instanceof CallSiteAwareMetaMethod) { return ((CallSiteAwareMetaMethod)metaMethod).createPojoCallSite(site, metaClass, metaMethod, params, receiver, args); } if (metaMethod.getClass() == CachedMethod.class) return createCachedMethodSite (site, metaClass, (CachedMethod) metaMethod, params, args); return createNonAwareCallSite(site, metaClass, metaMethod, params, args); }
public static CallSite createCachedMethodSite(CallSite site, MetaClassImpl metaClass, CachedMethod metaMethod, Class[] params, Object[] args) { if (metaMethod.correctArguments(args) == args) { if (noWrappers(args)) { if (noCoerce(metaMethod,args)) return new PojoCachedMethodSiteNoUnwrap(site, metaClass, metaMethod, params); else return metaMethod.createPojoMetaMethodSite(site, metaClass, params); } } return new PojoCachedMethodSite(site, metaClass, metaMethod, params); }
private static CallSite createNonAwareCallSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object[] args) { if (metaMethod.correctArguments(args) == args) { if (noWrappers(args)) { if (noCoerce(metaMethod,args)) return new PogoMetaMethodSiteNoUnwrap(site, metaClass, metaMethod, params); else { return new PogoMetaMethodSiteNoUnwrapNoCoerce(site, metaClass, metaMethod, params); } } } return new PogoMetaMethodSite(site, metaClass, metaMethod, params); }
public static CallSite createCachedMethodSite(CallSite site, MetaClassImpl metaClass, CachedMethod metaMethod, Class[] params, Object[] args) { if (metaMethod.correctArguments(args) == args) { if (noWrappers(args)) { if (noCoerce(metaMethod,args)) return new PogoCachedMethodSiteNoUnwrap(site, metaClass, metaMethod, params); else { return metaMethod.createPogoMetaMethodSite(site, metaClass, params); } } } return new PogoCachedMethodSite(site, metaClass, metaMethod, params); }
private static CallSite createCallConstructorSite(CallSite callSite, Class receiver, Object[] args) { MetaClass metaClass = InvokerHelper.getMetaClass(receiver); CallSite site; if (metaClass instanceof MetaClassImpl) { site = ((MetaClassImpl)metaClass).createConstructorSite(callSite, args); } else site = new MetaClassConstructorSite(callSite, metaClass); replaceCallSite(callSite, site); return site; }
public static ConstructorSite createConstructorSite(CallSite site, MetaClassImpl metaClass, CachedConstructor constructor, Class[] params, Object[] args) { if (constructor.correctArguments(args) == args) { if (noWrappers(args)) { if (noCoerce(constructor, args)) return new ConstructorSiteNoUnwrap(site, metaClass, constructor, params); else return new ConstructorSiteNoUnwrapNoCoerce(site, metaClass, constructor, params); } } return new ConstructorSite(site, metaClass, constructor, params); }
public final Object callConstructor(Object receiver, Object[] args) throws Throwable { if (checkCall(receiver, args)) { final Object bean = constructor.invoke(NO_ARGS); try { ((MetaClassImpl) metaClass).setProperties(bean, (Map) args[0]); } catch (GroovyRuntimeException gre) { throw ScriptBytecodeAdapter.unwrap(gre); } return bean; } else return CallSiteArray.defaultCallConstructor(this, receiver, args); }
public final Object callConstructor(Object receiver, Object[] args) throws Throwable { if (checkCall(receiver, args)) { final Object[] newArgs = new Object[] {args[0]}; final Object bean = constructor.invoke(newArgs); try { ((MetaClassImpl) metaClass).setProperties(bean, (Map) args[1]); } catch (GroovyRuntimeException gre) { throw ScriptBytecodeAdapter.unwrap(gre); } return bean; } else return CallSiteArray.defaultCallConstructor(this, receiver, args); }
/** * Returns the MetaClassImpl if the given MetaClass is one of * MetaClassImpl, AdaptingMetaClass or ClosureMetaClass. If * none of these cases matches, this method returns null. */ private static MetaClassImpl getMetaClassImpl(MetaClass mc, boolean includeEMC) { Class mcc = mc.getClass(); boolean valid = mcc == MetaClassImpl.class || mcc == AdaptingMetaClass.class || mcc == ClosureMetaClass.class || (includeEMC && mcc == ExpandoMetaClass.class); if (!valid) { if (LOG_ENABLED) LOG.info("meta class is neither MetaClassImpl, nor AdoptingMetaClass, nor ClosureMetaClass, normal method selection path disabled."); return null; } if (LOG_ENABLED) LOG.info("meta class is a recognized MetaClassImpl"); return (MetaClassImpl) mc; }
/** * Uses the meta class to get a meta method for a method call. * There will be no meta method selected, if the meta class is no MetaClassImpl * or the meta class is an AdaptingMetaClass. */ public void chooseMeta(MetaClassImpl mci) { if (mci==null) return; Object receiver = getCorrectedReceiver(); Object[] newArgs = removeRealReceiver(args); if (receiver instanceof Class) { if (LOG_ENABLED) LOG.info("receiver is a class"); if (!mci.hasCustomStaticInvokeMethod()) method = mci.retrieveStaticMethod(name, newArgs); } else { String changedName = name; if (receiver instanceof GeneratedClosure && changedName.equals("call")) {changedName = "doCall";} if (!mci.hasCustomInvokeMethod()) method = mci.getMethodWithCaching(selectionBase, changedName, newArgs, false); } if (LOG_ENABLED) LOG.info("retrieved method from meta class: "+method); }
public MetaClassConstant(Class<T> clazz) { impl = new MetaClassImpl(clazz); }
public FloatFloat(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
/** * this method chooses a property from the meta class. */ @Override public void chooseMeta(MetaClassImpl mci) { Object receiver = getCorrectedReceiver(); if (receiver instanceof GroovyObject) { Class aClass = receiver.getClass(); Method reflectionMethod = null; try { reflectionMethod = aClass.getMethod("getProperty", String.class); if (!reflectionMethod.isSynthetic()) { handle = MethodHandles.insertArguments(GROOVY_OBJECT_GET_PROPERTY, 1, name); return; } } catch (ReflectiveOperationException e) {} } else if (receiver instanceof Class) { handle = MOP_GET; handle = MethodHandles.insertArguments(handle, 2, name); handle = MethodHandles.insertArguments(handle, 0, this.mc); return; } if (method!=null || mci==null) return; Class chosenSender = this.sender; if (mci.getTheClass()!= chosenSender && GroovyCategorySupport.hasCategoryInCurrentThread()) { chosenSender = mci.getTheClass(); } MetaProperty res = mci.getEffectiveGetMetaProperty(chosenSender, receiver, name, false); if (res instanceof MethodMetaProperty) { MethodMetaProperty mmp = (MethodMetaProperty) res; method = mmp.getMetaMethod(); insertName = true; } else if (res instanceof CachedField) { CachedField cf = (CachedField) res; Field f = cf.field; try { handle = LOOKUP.unreflectGetter(f); if (Modifier.isStatic(f.getModifiers())) { // normally we would do the following // handle = MethodHandles.dropArguments(handle,0,Class.class); // but because there is a bug in invokedynamic in all jdk7 versions // maybe use Unsafe.ensureClassInitialized handle = META_PROPERTY_GETTER.bindTo(res); } } catch (IllegalAccessException iae) { throw new GroovyBugError(iae); } } else { handle = META_PROPERTY_GETTER.bindTo(res); } }
public GetEffectivePojoPropertySite(CallSite site, MetaClassImpl metaClass, MetaProperty effective) { super(site); this.metaClass = metaClass; this.effective = effective; version = metaClass.getVersion(); }
public LongDouble(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
public IntegerLong(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
public StaticMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) { super(site, metaClass, metaMethod, params); version = metaClass.getVersion (); }
public IntegerFloat(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
public Object getProperty(Object object) { return getMetaMethod().doMethodInvoke(object, MetaClassImpl.EMPTY_ARGUMENTS); }
public DoubleDouble(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
public FloatDouble(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
protected final boolean checkCall(Object receiver, Object arg1, Object arg2, Object arg3) { return receiver == metaClass.getTheClass() // meta class match receiver && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid && MetaClassHelper.sameClasses(params, arg1, arg2, arg3); }
protected final boolean checkCall(Object receiver, Object arg1, Object arg2, Object arg3, Object arg4) { return receiver == metaClass.getTheClass() // meta class match receiver && ((MetaClassImpl)metaClass).getVersion() == version // metaClass still be valid && MetaClassHelper.sameClasses(params, arg1, arg2, arg3, arg4); }
public LongFloat(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
public StaticMetaMethodSiteNoUnwrap(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) { super(site, metaClass, metaMethod, params); }
public StaticMetaMethodSiteNoUnwrapNoCoerce(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) { super(site, metaClass, metaMethod, params); }
public PojoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) { super(site, metaClass, metaMethod, params); version = metaClass.getVersion(); }
protected final boolean checkPojoMetaClass() { return !GroovyCategorySupport.hasCategoryInCurrentThread() && ((MetaClassImpl)metaClass).getVersion() == version; }
public FloatLong(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) { super(site, metaClass, metaMethod, params, (Number) receiver, (Number) args[0]); }
public PojoCachedMethodSiteNoUnwrap(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class params[]) { super(site, metaClass, metaMethod, params); }