Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix string modeling for springboot #2

Open
wants to merge 8 commits into
base: declarative-config
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,8 @@ public static void ensureInitialized() {

public static final Symbol<Signature> String_byte_array_int_int = StaticSymbols.putSignature(Type.java_lang_String, Type._byte_array, Type._int, Type._int);

public static final Symbol<Signature> _boolean_byte_array_byte_array = StaticSymbols.putSignature(Type._boolean, Type._byte_array, Type._byte_array);

public static final Symbol<Signature> _void_int_int_char_array_int = StaticSymbols.putSignature(Type._void, Type._int, Type._int, Type._char_array, Type._int);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1586,12 +1586,26 @@ public CodeAttribute getCodeAttribute() {
}
// endregion jdwp-specific

// spout
private Boolean partOfAnalysis = null;
private Integer modelId = null;

public boolean isPartOfAnalysis() {
if (partOfAnalysis == null) {
partOfAnalysis = SPouT.isPartOfAnalysis(this);
}
return partOfAnalysis;
}

public boolean hasModel(Meta meta) {
if (modelId == null) {
modelId = SPouT.getModelId(this, meta);
}
return modelId != -1;
}

public int getModelId() {
return modelId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
import com.oracle.truffle.espresso.runtime.StaticObject;
import com.oracle.truffle.espresso.substitutions.JavaType;
import com.oracle.truffle.espresso.vm.InterpreterToVM;
import tools.aqua.spout.SPouT;

/**
* Introspection API to access the guest world from the host. Provides seamless conversions from
Expand Down Expand Up @@ -838,6 +837,9 @@ public Meta(EspressoContext context) {

java_lang_StringLatin1 = knownKlass(Type.java_lang_StringLatin1);
java_lang_StringLatin1_newString = java_lang_StringLatin1.lookupMethod(getNames().getOrCreate("newString"), Signature.String_byte_array_int_int);
java_lang_StringLatin1_equals = java_lang_StringLatin1.lookupMethod(getNames().getOrCreate("equals"), Signature._boolean_byte_array_byte_array);

java_lang_String_equals = java_lang_String.lookupMethod(getNames().getOrCreate("equals"), Signature._boolean_Object);

java_lang_StringUTF16 = knownKlass(Type.java_lang_StringUTF16);
java_lang_StringUTF16_newString = java_lang_StringUTF16.lookupMethod(getNames().getOrCreate("newString"), Signature.String_byte_array_int_int);
Expand Down Expand Up @@ -1454,7 +1456,8 @@ private DiffVersionLoadHelper diff() {
public final ObjectKlass java_lang_StringLatin1;

public final Method java_lang_StringLatin1_newString;

public final Method java_lang_StringLatin1_equals;
public final Method java_lang_String_equals;
public final ObjectKlass java_lang_StringUTF16;

public final Method java_lang_StringUTF16_newString;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@
import static com.oracle.truffle.espresso.bytecode.Bytecodes.TABLESWITCH;
import static com.oracle.truffle.espresso.bytecode.Bytecodes.WIDE;

import java.lang.invoke.SwitchPoint;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -298,6 +297,7 @@
import com.oracle.truffle.espresso.meta.ExceptionHandler;
import com.oracle.truffle.espresso.meta.JavaKind;
import com.oracle.truffle.espresso.meta.Meta;
import com.oracle.truffle.espresso.nodes.concolic.ConcolicInvokeVirtualNode;
import com.oracle.truffle.espresso.nodes.helper.EspressoReferenceArrayStoreNode;
import com.oracle.truffle.espresso.nodes.quick.BaseQuickNode;
import com.oracle.truffle.espresso.nodes.quick.CheckCastQuickNode;
Expand Down Expand Up @@ -342,7 +342,6 @@

import tools.aqua.spout.*;
import tools.aqua.taint.PostDominatorAnalysis;
import tools.aqua.taint.TaintAnalysis;

/**
* Bytecode interpreter loop.
Expand Down Expand Up @@ -2136,11 +2135,16 @@ private void putPoolConstant(VirtualFrame frame, int top, char cpi, int opcode)
} else if (constant instanceof StringConstant) {
assert opcode == LDC || opcode == LDC_W;
StaticObject internedString = pool.resolvedStringAt(cpi);
Meta meta = getMeta();
StaticObject obj = meta.toGuestString(meta.toHostString(internedString));
SPouT.markObjectWithIFTaint(obj);
//TODO: (annotate string and maybe clone?)
putObject(frame, top, obj);
//TODO: (this is definitively not correct! Maybe clone properly and annotate?)
if (SPouT.generateIFTaint()) {
Meta meta = getMeta();
StaticObject obj = meta.toGuestString(meta.toHostString(internedString));
SPouT.markObjectWithIFTaint(obj);
putObject(frame, top, obj);
}
else {
putObject(frame, top, internedString);
}
} else if (constant instanceof ClassConstant) {
assert opcode == LDC || opcode == LDC_W;
Klass klass = pool.resolvedKlassAt(getDeclaringKlass(), cpi);
Expand Down Expand Up @@ -2488,6 +2492,12 @@ private BaseQuickNode dispatchQuickened(int top, int curBCI, char cpi, int opcod
}
// @formatter:on
}

Meta meta = getMeta();
if (resolved.hasModel(meta)) {
invoke = SPouT.injectModel(resolved, meta, top, curBCI);
}

return invoke;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.oracle.truffle.espresso.nodes.concolic;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.espresso.descriptors.Signatures;
import com.oracle.truffle.espresso.descriptors.Types;
import com.oracle.truffle.espresso.impl.Method;
import com.oracle.truffle.espresso.meta.Meta;
import com.oracle.truffle.espresso.nodes.BytecodeNode;
import com.oracle.truffle.espresso.nodes.bytecodes.InvokeVirtual;
import com.oracle.truffle.espresso.nodes.bytecodes.InvokeVirtualNodeGen;
import com.oracle.truffle.espresso.nodes.quick.QuickNode;
import com.oracle.truffle.espresso.runtime.StaticObject;
import tools.aqua.spout.SPouT;

public abstract class ConcolicInvokeVirtualNode extends QuickNode {

final Meta meta;
final Method.MethodVersion method;
final int resultAt;
final boolean returnsPrimitiveType;
@Child InvokeVirtual.WithoutNullCheck invokeVirtual;

abstract Object concolicAnalysis(Object concreteResult, Object[] args);

public ConcolicInvokeVirtualNode(Method method, int top, int curBCI, Meta meta) {
super(top, curBCI);
assert !method.isStatic();
this.method = method.getMethodVersion();
this.resultAt = top - Signatures.slotsForParameters(method.getParsedSignature()) - 1; // -receiver
this.returnsPrimitiveType = Types.isPrimitive(Signatures.returnType(method.getParsedSignature()));
this.invokeVirtual = InvokeVirtualNodeGen.WithoutNullCheckNodeGen.create(method);
this.meta = meta;
}

@Override
public int execute(VirtualFrame frame) {
Object[] args = BytecodeNode.popArguments(frame, top, true, method.getMethod().getParsedSignature());
nullCheck((StaticObject) args[0]);
Object result = invokeVirtual.execute(args);
result = concolicAnalysis(result, args);
if (!returnsPrimitiveType) {
getBytecodeNode().checkNoForeignObjectAssumption((StaticObject) result);
}
return (getResultAt() - top) + BytecodeNode.putKind(frame, getResultAt(), result, method.getMethod().getReturnKind());
}

@Override
public boolean removedByRedefintion() {
if (method.getRedefineAssumption().isValid()) {
return false;
} else {
return method.getMethod().isRemovedByRedefition();
}
}

private int getResultAt() {
return resultAt;
}


public static final class StringEquals extends ConcolicInvokeVirtualNode {

public StringEquals(int top, int curBCI, Meta meta) {
super(meta.java_lang_String_equals, top, curBCI, meta);
}

@Override
Object concolicAnalysis(Object concreteResult, Object[] args) {
SPouT.log("concolic virtual node");
return SPouT.stringEquals( (StaticObject) args[0], (StaticObject) args[1], (boolean) concreteResult, meta);
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ public static void init(@JavaType(String.class) StaticObject self, @JavaType(Str
@Inject Meta meta) {
return SPouT.stringCompareTo(self, other, meta);
}

/*
@Substitution(hasReceiver = true)
public static @JavaType(internalName = "Z") Object equals(
@JavaType(String.class) StaticObject self,
@JavaType(Object.class) StaticObject other,
@Inject Meta meta) {
return SPouT.stringEquals(self, other, meta);
}

*/
@Substitution(hasReceiver = true)
public static @JavaType(internalName = "C") Object charAt(@JavaType(String.class) StaticObject self,
@JavaType(internalName = "I") Object index,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.oracle.truffle.espresso.meta.Meta;
import com.oracle.truffle.espresso.runtime.EspressoException;
import com.oracle.truffle.espresso.runtime.StaticObject;
import tools.aqua.spout.SPouT;

/**
* This substitution is merely for performance reasons, to avoid the deep-dive to native. libjava
Expand Down Expand Up @@ -340,7 +341,13 @@ public static Object checkAndWiden(Meta meta, StaticObject arg, Klass targetKlas

Object result;
try {
if (method.isPartOfAnalysis()) {
adjustedArgs = SPouT.processMethodCall(adjustedArgs, method, meta);
}
result = method.invokeDirect(receiver, adjustedArgs);
// if (method.isPartOfAnalysis()) {
// result = SPouT.processReturnValue(result, method, meta);
// }
} catch (EspressoException e) {
throw meta.throwExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, e.getGuestException());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public Object[] getAnnotations() {

@SuppressWarnings("unchecked")
public static <T> T annotation(Annotations a, int i) {
return a != null ? (T) a.annotations[i] : null;
if (a == null || i < 0 || a.annotations.length <= i) return null;
return (T) a.annotations[i];
}

@SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ public void walk(EspressoLanguage lang) {
visited.add(origin);
while (!queue.isEmpty()) {
StaticObject current = queue.poll();
if (current.isString()) {
action.applyToString(current);
continue;
}
action.applyToObject(current);
//SPouT.log("Analyzing " + current.getKlass().getNameAsString() + " . " + current.toString());
ObjectKlass oClass = (ObjectKlass) current.getKlass();
Expand Down Expand Up @@ -113,25 +117,27 @@ private void processArray(StaticObject arr, EspressoLanguage lang,
assert arr.isArray();
action.applyToArray(arr);
Klass eClass = arr.getKlass().getElementalType();
Object[] data = arr.unwrap(lang);
if (eClass.isPrimitive()) {
for (int i=0; i<data.length; i++) {
for (int i=0; i<arr.length(lang); i++) {
action.applyToPrimitiveArrayElement(arr, i);
}
}
else if (eClass.getType() == Symbol.Type.java_lang_String) {
Object[] data = arr.unwrap(lang);
for (Object e : data) {
StaticObject str = (StaticObject) e;
action.applyToString(str);
}
} else if (eClass.isArray()) {
Object[] data = arr.unwrap(lang);
for (Object e : data) {
StaticObject arr2 = (StaticObject) e;
if (visited.contains(arr2)) continue;
visited.add(arr2);
processArray( arr2, lang, nextQueue, visited);
}
} else {
Object[] data = arr.unwrap(lang);
for (Object e : data) {
StaticObject obj2 = (StaticObject) e;
if (visited.contains(obj2)) continue;
Expand Down
Loading
Loading