fix: i hate wrappers

This commit is contained in:
TopchetoEU 2024-03-28 15:10:21 +02:00
parent d38b600366
commit 18f70a0d58
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
2 changed files with 42 additions and 22 deletions

View File

@ -10,12 +10,8 @@ public class NativeWrapper extends ObjectValue {
public ObjectValue getPrototype(Context ctx) { public ObjectValue getPrototype(Context ctx) {
if (ctx.environment != null && prototype == NATIVE_PROTO) { if (ctx.environment != null && prototype == NATIVE_PROTO) {
var clazz = wrapped.getClass(); var clazz = wrapped.getClass();
var res = ctx.environment.wrappers.getProto(clazz);
while (true) { if (res != null) return res;
var res = ctx.environment.wrappers.getProto(clazz);
if (res != null) return res;
clazz = clazz.getSuperclass();
}
} }
return super.getPrototype(ctx); return super.getPrototype(ctx);
} }

View File

@ -288,6 +288,21 @@ public class NativeWrapperProvider implements WrapperProvider {
return res; return res;
} }
private void updateProtoChain(Class<?> clazz, ObjectValue proto, FunctionValue constr) {
var parent = clazz;
while (true) {
parent = parent.getSuperclass();
if (parent == null) return;
var parentProto = getProto(parent);
var parentConstr = getConstr(parent);
if (parentProto != null) Values.setPrototype(Context.NULL, proto, parentProto);
if (parentConstr != null) Values.setPrototype(Context.NULL, constr, parentConstr);
}
}
private void initType(Class<?> clazz, FunctionValue constr, ObjectValue proto) { private void initType(Class<?> clazz, FunctionValue constr, ObjectValue proto) {
if (constr != null && proto != null || ignore.contains(clazz)) return; if (constr != null && proto != null || ignore.contains(clazz)) return;
// i vomit // i vomit
@ -316,32 +331,35 @@ public class NativeWrapperProvider implements WrapperProvider {
prototypes.put(clazz, proto); prototypes.put(clazz, proto);
constructors.put(clazz, constr); constructors.put(clazz, constr);
var parent = clazz; updateProtoChain(clazz, proto, constr);
while (true) {
parent = parent.getSuperclass();
if (parent == null) return;
var parentProto = getProto(parent);
var parentConstr = getConstr(parent);
if (parentProto != null) Values.setPrototype(Context.NULL, proto, parentProto);
if (parentConstr != null) Values.setPrototype(Context.NULL, constr, parentConstr);
}
} }
public ObjectValue getProto(Class<?> clazz) { public ObjectValue getProto(Class<?> clazz) {
initType(clazz, constructors.get(clazz), prototypes.get(clazz)); initType(clazz, constructors.get(clazz), prototypes.get(clazz));
return prototypes.get(clazz); while (clazz != null) {
var res = prototypes.get(clazz);
if (res != null) return res;
clazz = clazz.getSuperclass();
}
return null;
} }
public ObjectValue getNamespace(Class<?> clazz) { public ObjectValue getNamespace(Class<?> clazz) {
if (!namespaces.containsKey(clazz)) namespaces.put(clazz, makeNamespace(env, clazz)); if (!namespaces.containsKey(clazz)) namespaces.put(clazz, makeNamespace(env, clazz));
return namespaces.get(clazz); while (clazz != null) {
var res = namespaces.get(clazz);
if (res != null) return res;
clazz = clazz.getSuperclass();
}
return null;
} }
public FunctionValue getConstr(Class<?> clazz) { public FunctionValue getConstr(Class<?> clazz) {
initType(clazz, constructors.get(clazz), prototypes.get(clazz)); initType(clazz, constructors.get(clazz), prototypes.get(clazz));
return constructors.get(clazz); while (clazz != null) {
var res = constructors.get(clazz);
if (res != null) return res;
clazz = clazz.getSuperclass();
}
return null;
} }
@Override public WrapperProvider fork(Environment env) { @Override public WrapperProvider fork(Environment env) {
@ -357,6 +375,12 @@ public class NativeWrapperProvider implements WrapperProvider {
prototypes.put(clazz, proto); prototypes.put(clazz, proto);
constructors.put(clazz, constructor); constructors.put(clazz, constructor);
ignore.remove(clazz); ignore.remove(clazz);
for (var el : prototypes.keySet()) {
if (clazz.isAssignableFrom(el)) {
updateProtoChain(el, getProto(el), getConstr(el));
}
}
} }
else { else {
prototypes.remove(clazz); prototypes.remove(clazz);