Code generation patches for fuzzer (feedback requested)
André Bargull
andrebargull at googlemail.com
Tue Oct 15 04:16:37 PDT 2013
(5) EnforceObjectTypeForNull.patch
This one looks like a bug in asm's frame computation, adding a
`checkcast` instruction makes sure things work as expected...
test cases:
function f(){ try { var x = 1, x = null; } catch(x2) {} }
function f(){ try { var x = 1; x = null; } catch(x2) {} return x }
- André
On 10/15/2013 10:45 AM, André Bargull wrote:
> I've needed to apply the following patches to continue fuzzing. If
> those changes look reasonable, can someone make sure they get into the
> upstream repo?
>
> - André
>
>
> (1) IncompatibleAssignmentCoercion.patch:
>
> `Type.widest(Type, Type)` can promote boolean -> number, or number ->
> string. This is not wanted for (?:) - ConditionalExpressions or
> ReturnStatements. Added a new uncoercedWidest(Type, Type) method to
> Attr which makes sure only valid promotions are applied.
>
> test cases:
> /* no verify error */ function f1(c,x){ c (x ? [1] : 1); }
> function f2(c,x){ c = (x ? "123" : 1); return c }
> typeof f2(null,true) === "string"
> typeof f2(null,false) === "number"
> function f3(v){if (v) return 123; else return true}
> f3(true) === 123
> f3(false) === true
>
>
> (2) JDK-8026249-WidenDISCARD.patch:
>
> The left-hand side of a BinaryNode does not have a Type if it is a
> Discard node, that means `lhs.getType()` may throw an assertion error.
> Moving the Type.widest() calls makes sure `lhs.getType()` is only
> called when it is safe to do.
>
> test case:
> /* no assertion */ function f() { if(x3, y) x; }
>
>
> (3) JDK-8026249-EnsureTypeDiscard.patch:
>
> The type for a CommaRight BinaryNode is based on the right-hand side's
> type, make sure the RHS always has a proper type attached. [I've also
> fixed this for CommaLeft, but that one isn't actually used, is it?]
>
> test case:
> /* no assertion */ function f(x) { return y, x }
>
>
> (4) JDK-8026249-ControlFlowEscape.patch:
>
> Control flow may escape from SwitchNode or LabelNode through `break`
> or `continue` statements. Simply moving the "controlFlowEscapes" logic
> from LoopNode to BreakableStatement solves the SwitchNode issue. And
> for LabelNode just clear the "terminal" on its body node.
>
> test cases:
> /* no verify error / NPE */ function f() { L: { try { return 1; }
> finally { break L; }} }
> /* no verify error / NPE */ function f() { L: { if (v) break L; return} }
> /* no verify error / NPE */ function f() { L: {{ break L; } return; } }
> /* no verify error / NPE */ function f() { L: { if (x2) { break L; }
> throw x; } }
> /* no verify error / NPE */ function f() { switch(v) { default: if(v)
> break; return; } }
> /* no verify error / NPE */ function f() { switch(x) { default:
> if(true) break; return; } }
> /* no verify error / NPE */ function f() { switch(x) { default: L:
> break; return; } }
-------------- next part --------------
diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -1333,6 +1333,7 @@
if (value == null) {
method.loadNull();
+ method.checkcast(Object.class); // enforce Object type for asm
} else if (value instanceof Undefined) {
method.loadUndefined(Type.OBJECT);
} else if (value instanceof String) {
More information about the nashorn-dev
mailing list