From cd19d6168551ec7bd1da12e24f6e3e5288f79958 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Tue, 15 May 2018 19:17:39 +0200 Subject: [PATCH] Improvements to MemberBox (#438) --- .../mozilla/javascript/FunctionObject.java | 18 ++--- src/org/mozilla/javascript/JavaMembers.java | 18 ++--- src/org/mozilla/javascript/MemberBox.java | 74 ++++++------------- .../mozilla/javascript/NativeJavaClass.java | 4 +- .../javascript/NativeJavaConstructor.java | 2 +- .../mozilla/javascript/NativeJavaMethod.java | 36 ++++----- .../mozilla/javascript/ScriptableObject.java | 2 +- 7 files changed, 60 insertions(+), 94 deletions(-) diff --git a/src/org/mozilla/javascript/FunctionObject.java b/src/org/mozilla/javascript/FunctionObject.java index 1d396a6c85..f39071e00a 100644 --- a/src/org/mozilla/javascript/FunctionObject.java +++ b/src/org/mozilla/javascript/FunctionObject.java @@ -91,7 +91,7 @@ public FunctionObject(String name, Member methodOrConstructor, } String methodName = member.getName(); this.functionName = name; - Class[] types = member.argTypes; + Class[] types = member.argTypes(); int arity = types.length; if (arity == 4 && (types[1].isArray() || types[2].isArray())) { // Either variable args or an error. @@ -134,8 +134,7 @@ public FunctionObject(String name, Member methodOrConstructor, } if (member.isMethod()) { - Method method = member.method(); - Class returnType = method.getReturnType(); + Class returnType = member.getReturnType(); if (returnType == Void.TYPE) { hasVoidReturn = true; } else { @@ -235,13 +234,9 @@ public String getFunctionName() /** * Get Java method or constructor this function represent. */ - public Member getMethodOrConstructor() + public Executable getMethodOrConstructor() { - if (member.isMethod()) { - return member.method(); - } else { - return member.ctor(); - } + return member.member(); } static Method findSingleMethod(Method[] methods, String name) @@ -506,15 +501,14 @@ private void readObject(ObjectInputStream in) { in.defaultReadObject(); if (parmsLength > 0) { - Class[] types = member.argTypes; + Class[] types = member.argTypes(); typeTags = new byte[parmsLength]; for (int i = 0; i != parmsLength; ++i) { typeTags[i] = (byte)getTypeTag(types[i]); } } if (member.isMethod()) { - Method method = member.method(); - Class returnType = method.getReturnType(); + Class returnType = member.getReturnType(); if (returnType == Void.TYPE) { hasVoidReturn = true; } else { diff --git a/src/org/mozilla/javascript/JavaMembers.java b/src/org/mozilla/javascript/JavaMembers.java index 02a0124eb8..d555744559 100644 --- a/src/org/mozilla/javascript/JavaMembers.java +++ b/src/org/mozilla/javascript/JavaMembers.java @@ -83,7 +83,7 @@ Object get(Scriptable scope, String name, Object javaObject, if (bp.getter == null) return Scriptable.NOT_FOUND; rval = bp.getter.invoke(javaObject, Context.emptyArgs); - type = bp.getter.method().getReturnType(); + type = bp.getter.getReturnType(); } else { Field field = (Field) member; rval = field.get(isStatic ? null : javaObject); @@ -123,7 +123,7 @@ void put(Scriptable scope, String name, Object javaObject, // main setter. Otherwise, let the NativeJavaMethod decide which // setter to use: if (bp.setters == null || value == null) { - Class setType = bp.setter.argTypes[0]; + Class setType = bp.setter.argTypes()[0]; Object[] args = { Context.jsToJava(value, setType) }; try { bp.setter.invoke(javaObject, args); @@ -239,7 +239,7 @@ private MemberBox findExplicitFunction(String name, boolean isStatic) if (methodsOrCtors != null) { for (MemberBox methodsOrCtor : methodsOrCtors) { - Class[] type = methodsOrCtor.argTypes; + Class[] type = methodsOrCtor.argTypes(); String sig = liveConnectSignature(type); if (sigStart + sig.length() == name.length() && name.regionMatches(sigStart, sig, 0, sig.length())) @@ -602,7 +602,7 @@ private void reflect(Scriptable scope, if (getter != null) { // We have a getter. Now, do we have a matching // setter? - Class type = getter.method().getReturnType(); + Class type = getter.getReturnType(); setter = extractSetMethod(type, njmSet.methods, isStatic); } else { @@ -713,8 +713,8 @@ private static MemberBox extractGetMethod(MemberBox[] methods, for (MemberBox method : methods) { // Does getter method have an empty parameter list with a return // value (eg. a getSomething() or isSomething())? - if (method.argTypes.length == 0 && (!isStatic || method.isStatic())) { - Class type = method.method().getReturnType(); + if (method.member().getParameterCount() == 0 && (!isStatic || method.isStatic())) { + Class type = method.getReturnType(); if (type != Void.TYPE) { return method; } @@ -738,7 +738,7 @@ private static MemberBox extractSetMethod(Class type, MemberBox[] methods, for (int pass = 1; pass <= 2; ++pass) { for (MemberBox method : methods) { if (!isStatic || method.isStatic()) { - Class[] params = method.argTypes; + Class[] params = method.argTypes(); if (params.length == 1) { if (pass == 1) { if (params[0] == type) { @@ -763,8 +763,8 @@ private static MemberBox extractSetMethod(MemberBox[] methods, for (MemberBox method : methods) { if (!isStatic || method.isStatic()) { - if (method.method().getReturnType() == Void.TYPE) { - if (method.argTypes.length == 1) { + if (method.getReturnType() == Void.TYPE) { + if (method.member().getParameterCount() == 1) { return method; } } diff --git a/src/org/mozilla/javascript/MemberBox.java b/src/org/mozilla/javascript/MemberBox.java index 140dee485c..3117d09885 100644 --- a/src/org/mozilla/javascript/MemberBox.java +++ b/src/org/mozilla/javascript/MemberBox.java @@ -21,49 +21,32 @@ final class MemberBox implements Serializable { static final long serialVersionUID = 6358550398665688245L; - private transient Member memberObject; - transient Class[] argTypes; - transient Object delegateTo; - transient boolean vararg; + private transient Executable memberObject; + Object delegateTo; - - MemberBox(Method method) - { - init(method); - } - - MemberBox(Constructor constructor) - { - init(constructor); - } - - private void init(Method method) + MemberBox(Executable executable) { - this.memberObject = method; - this.argTypes = method.getParameterTypes(); - this.vararg = method.isVarArgs(); + this.memberObject = executable; } - private void init(Constructor constructor) + Executable member() { - this.memberObject = constructor; - this.argTypes = constructor.getParameterTypes(); - this.vararg = constructor.isVarArgs(); + return memberObject; } - Method method() + Class[] argTypes() { - return (Method)memberObject; + return memberObject.getParameterTypes(); } - Constructor ctor() + Class getReturnType() { - return (Constructor)memberObject; + return ((Method)memberObject).getReturnType(); } - Member member() + boolean vararg() { - return memberObject; + return memberObject.isVarArgs(); } boolean isMethod() @@ -95,20 +78,18 @@ String toJavaDeclaration() { StringBuilder sb = new StringBuilder(); if (isMethod()) { - Method method = method(); - sb.append(method.getReturnType()); + sb.append(getReturnType()); sb.append(' '); - sb.append(method.getName()); + sb.append(memberObject.getName()); } else { - Constructor ctor = ctor(); - String name = ctor.getDeclaringClass().getName(); + String name = memberObject.getDeclaringClass().getName(); int lastDot = name.lastIndexOf('.'); if (lastDot >= 0) { name = name.substring(lastDot + 1); } sb.append(name); } - sb.append(JavaMembers.liveConnectSignature(argTypes)); + sb.append(JavaMembers.liveConnectSignature(argTypes())); return sb.toString(); } @@ -120,12 +101,12 @@ public String toString() Object invoke(Object target, Object[] args) { - Method method = method(); + Method method = (Method)memberObject; try { try { return method.invoke(target, args); } catch (IllegalAccessException ex) { - Method accessible = searchAccessibleMethod(method, argTypes); + Method accessible = searchAccessibleMethod(method, argTypes()); if (accessible != null) { memberObject = accessible; method = accessible; @@ -153,7 +134,7 @@ Object invoke(Object target, Object[] args) Object newInstance(Object[] args) { - Constructor ctor = ctor(); + Constructor ctor = (Constructor)memberObject; try { try { return ctor.newInstance(args); @@ -210,12 +191,7 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); - Member member = readMember(in); - if (member instanceof Method) { - init((Method)member); - } else { - init((Constructor)member); - } + memberObject = readMember(in); } private void writeObject(ObjectOutputStream out) @@ -232,7 +208,7 @@ private void writeObject(ObjectOutputStream out) * information about the class, the name, and the parameters and * recreate upon deserialization. */ - private static void writeMember(ObjectOutputStream out, Member member) + private static void writeMember(ObjectOutputStream out, Executable member) throws IOException { if (member == null) { @@ -245,17 +221,13 @@ private static void writeMember(ObjectOutputStream out, Member member) out.writeBoolean(member instanceof Method); out.writeObject(member.getName()); out.writeObject(member.getDeclaringClass()); - if (member instanceof Method) { - writeParameters(out, ((Method) member).getParameterTypes()); - } else { - writeParameters(out, ((Constructor) member).getParameterTypes()); - } + writeParameters(out, member.getParameterTypes()); } /** * Reads a Method or a Constructor from the stream. */ - private static Member readMember(ObjectInputStream in) + private static Executable readMember(ObjectInputStream in) throws IOException, ClassNotFoundException { if (!in.readBoolean()) diff --git a/src/org/mozilla/javascript/NativeJavaClass.java b/src/org/mozilla/javascript/NativeJavaClass.java index d2f451c5d5..97f26d0a7b 100644 --- a/src/org/mozilla/javascript/NativeJavaClass.java +++ b/src/org/mozilla/javascript/NativeJavaClass.java @@ -211,9 +211,9 @@ static Scriptable constructSpecific(Context cx, Scriptable scope, static Object constructInternal(Object[] args, MemberBox ctor) { - Class[] argTypes = ctor.argTypes; + Class[] argTypes = ctor.argTypes(); - if (ctor.vararg) { + if (ctor.vararg()) { // marshall the explicit parameter Object[] newArgs = new Object[argTypes.length]; for (int i = 0; i < argTypes.length-1; i++) { diff --git a/src/org/mozilla/javascript/NativeJavaConstructor.java b/src/org/mozilla/javascript/NativeJavaConstructor.java index 3b44dde4ed..2dbe8a7177 100644 --- a/src/org/mozilla/javascript/NativeJavaConstructor.java +++ b/src/org/mozilla/javascript/NativeJavaConstructor.java @@ -41,7 +41,7 @@ public Object call(Context cx, Scriptable scope, Scriptable thisObj, @Override public String getFunctionName() { - String sig = JavaMembers.liveConnectSignature(ctor.argTypes); + String sig = JavaMembers.liveConnectSignature(ctor.argTypes()); return "".concat(sig); } diff --git a/src/org/mozilla/javascript/NativeJavaMethod.java b/src/org/mozilla/javascript/NativeJavaMethod.java index 11e25e9818..a117acb973 100644 --- a/src/org/mozilla/javascript/NativeJavaMethod.java +++ b/src/org/mozilla/javascript/NativeJavaMethod.java @@ -113,15 +113,15 @@ public String toString() StringBuilder sb = new StringBuilder(); for (int i = 0, N = methods.length; i != N; ++i) { // Check member type, we also use this for overloaded constructors - if (methods[i].isMethod()) { - Method method = methods[i].method(); - sb.append(JavaMembers.javaSignature(method.getReturnType())); + MemberBox member = methods[i]; + if (member.isMethod()) { + sb.append(JavaMembers.javaSignature(member.getReturnType())); sb.append(' '); - sb.append(method.getName()); + sb.append(member.getName()); } else { - sb.append(methods[i].getName()); + sb.append(member.getName()); } - sb.append(JavaMembers.liveConnectSignature(methods[i].argTypes)); + sb.append(JavaMembers.liveConnectSignature(member.argTypes())); sb.append('\n'); } return sb.toString(); @@ -138,16 +138,16 @@ public Object call(Context cx, Scriptable scope, Scriptable thisObj, int index = findCachedFunction(cx, args); if (index < 0) { - Class c = methods[0].method().getDeclaringClass(); + Class c = methods[0].member().getDeclaringClass(); String sig = c.getName() + '.' + getFunctionName() + '(' + scriptSignature(args) + ')'; throw Context.reportRuntimeError1("msg.java.no_such_method", sig); } MemberBox meth = methods[index]; - Class[] argTypes = meth.argTypes; + Class[] argTypes = meth.argTypes(); - if (meth.vararg) { + if (meth.vararg()) { // marshall the explicit parameters Object[] newArgs = new Object[argTypes.length]; for (int i = 0; i < argTypes.length-1; i++) { @@ -223,7 +223,7 @@ public Object call(Context cx, Scriptable scope, Scriptable thisObj, } Object retval = meth.invoke(javaObject, args); - Class staticType = meth.method().getReturnType(); + Class staticType = meth.getReturnType(); if (debug) { Class actualType = (retval == null) ? null @@ -287,10 +287,10 @@ static int findFunction(Context cx, return -1; } else if (methodsOrCtors.length == 1) { MemberBox member = methodsOrCtors[0]; - Class[] argTypes = member.argTypes; + Class[] argTypes = member.argTypes(); int alength = argTypes.length; - if (member.vararg) { + if (member.vararg()) { alength--; if ( alength > args.length) { return -1; @@ -318,9 +318,9 @@ static int findFunction(Context cx, search: for (int i = 0; i < methodsOrCtors.length; i++) { MemberBox member = methodsOrCtors[i]; - Class[] argTypes = member.argTypes; + Class[] argTypes = member.argTypes(); int alength = argTypes.length; - if (member.vararg) { + if (member.vararg()) { alength--; if ( alength > args.length) { continue search; @@ -370,9 +370,9 @@ static int findFunction(Context cx, ++worseCount; } else { int preference = preferSignature(args, argTypes, - member.vararg, - bestFit.argTypes, - bestFit.vararg ); + member.vararg(), + bestFit.argTypes(), + bestFit.vararg() ); if (preference == PREFERENCE_AMBIGUOUS) { break; } else if (preference == PREFERENCE_FIRST_ARG) { @@ -547,7 +547,7 @@ private static void printDebug(String msg, MemberBox member, if (member.isMethod()) { sb.append(member.getName()); } - sb.append(JavaMembers.liveConnectSignature(member.argTypes)); + sb.append(JavaMembers.liveConnectSignature(member.argTypes())); sb.append(" for arguments ("); sb.append(scriptSignature(args)); sb.append(')'); diff --git a/src/org/mozilla/javascript/ScriptableObject.java b/src/org/mozilla/javascript/ScriptableObject.java index 97552d5941..541f904a3e 100644 --- a/src/org/mozilla/javascript/ScriptableObject.java +++ b/src/org/mozilla/javascript/ScriptableObject.java @@ -293,7 +293,7 @@ boolean setValue(Object value, Scriptable owner, Scriptable start) { Context cx = Context.getContext(); if (setter instanceof MemberBox) { MemberBox nativeSetter = (MemberBox)setter; - Class pTypes[] = nativeSetter.argTypes; + Class pTypes[] = nativeSetter.argTypes(); // XXX: cache tag since it is already calculated in // defineProperty ? Class valueType = pTypes[pTypes.length - 1];