@SuppressWarnings("rawtypes") @Override public boolean enterLiteralNode(final LiteralNode literalNode) { if (literalNode instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode; final Expression[] array = arrayLiteralNode.getValue(); final Type elementType = arrayLiteralNode.getElementType(); for (int i = 0; i < array.length; i++) { final Node element = array[i]; if (element != null) { array[i] = convert((Expression)element.accept(this), elementType); } } } return false; }
@Override public Node leaveLiteralNode(final LiteralNode<?> node) { if (node instanceof ArrayLiteralNode) { final ArrayLiteralNode aln = (ArrayLiteralNode)node; if (aln.getUnits() == null) { return node; } final List<ArrayUnit> newArrayUnits = new ArrayList<>(); for (final ArrayUnit au : aln.getUnits()) { newArrayUnits.add(new ArrayUnit(getExistingReplacement(au), au.getLo(), au.getHi())); } return aln.setUnits(lc, newArrayUnits); } return node; }
private static boolean isSplitArray(final LexicalContextNode expr) { if(!(expr instanceof ArrayLiteralNode)) { return false; } final List<ArrayUnit> units = ((ArrayLiteralNode)expr).getUnits(); return !(units == null || units.isEmpty()); }
@SuppressWarnings("rawtypes") @Override public boolean enterLiteralNode(final LiteralNode literalNode) { weight += LITERAL_WEIGHT; if (literalNode instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode; final Node[] value = arrayLiteralNode.getValue(); final int[] postsets = arrayLiteralNode.getPostsets(); final List<ArrayUnit> units = arrayLiteralNode.getUnits(); if (units == null) { for (final int postset : postsets) { weight += AASTORE_WEIGHT; final Node element = value[postset]; if (element != null) { element.accept(this); } } } return false; } return true; }
@Override public Node leaveLiteralNode(final LiteralNode<?> node) { if (node instanceof ArrayLiteralNode) { final ArrayLiteralNode aln = (ArrayLiteralNode)node; if (aln.getSplitRanges() == null) { return node; } final List<Splittable.SplitRange> newArrayUnits = new ArrayList<>(); for (final Splittable.SplitRange au : aln.getSplitRanges()) { newArrayUnits.add(new Splittable.SplitRange(getExistingReplacement(au), au.getLow(), au.getHigh())); } return aln.setSplitRanges(lc, newArrayUnits); } return node; }
@Override public boolean enterForNode(final ForNode forNode) { if (es6 && (forNode.getInit() instanceof ObjectNode || forNode.getInit() instanceof ArrayLiteralNode)) { throwNotImplementedYet("es6.destructuring", forNode); } return super.enterForNode(forNode); }
@Override public boolean enterASSIGN(BinaryNode binaryNode) { if (es6 && (binaryNode.lhs() instanceof ObjectNode || binaryNode.lhs() instanceof ArrayLiteralNode)) { throwNotImplementedYet("es6.destructuring", binaryNode); } return super.enterASSIGN(binaryNode); }
@Override public boolean enterLiteralNode(final LiteralNode<?> literalNode) { if (literalNode instanceof ArrayLiteralNode) { final List<Expression> expressions = ((ArrayLiteralNode)literalNode).getElementExpressions(); if (expressions != null) { visitExpressions(expressions); } } pushExpressionType(literalNode); return false; }
/** * Load a list of nodes as an array of a specific type * The array will contain the visited nodes. * * @param arrayLiteralNode the array of contents * @param arrayType the type of the array, e.g. ARRAY_NUMBER or ARRAY_OBJECT */ private void loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) { assert arrayType == Type.INT_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY; final Expression[] nodes = arrayLiteralNode.getValue(); final Object presets = arrayLiteralNode.getPresets(); final int[] postsets = arrayLiteralNode.getPostsets(); final List<Splittable.SplitRange> ranges = arrayLiteralNode.getSplitRanges(); loadConstant(presets); final Type elementType = arrayType.getElementType(); if (ranges != null) { loadSplitLiteral(new SplitLiteralCreator() { @Override public void populateRange(final MethodEmitter method, final Type type, final int slot, final int start, final int end) { for (int i = start; i < end; i++) { method.load(type, slot); storeElement(nodes, elementType, postsets[i]); } method.load(type, slot); } }, ranges, arrayType); return; } if(postsets.length > 0) { final int arraySlot = method.getUsedSlotsWithLiveTemporaries(); method.storeTemp(arrayType, arraySlot); for (final int postset : postsets) { method.load(arrayType, arraySlot); storeElement(nodes, elementType, postset); } method.load(arrayType, arraySlot); } }
@SuppressWarnings("rawtypes") @Override public boolean enterLiteralNode(final LiteralNode literalNode) { weight += LITERAL_WEIGHT; if (literalNode instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode; final Node[] value = arrayLiteralNode.getValue(); final int[] postsets = arrayLiteralNode.getPostsets(); final List<Splittable.SplitRange> units = arrayLiteralNode.getSplitRanges(); if (units == null) { for (final int postset : postsets) { weight += AASTORE_WEIGHT; final Node element = value[postset]; if (element != null) { element.accept(this); } } } return false; } return true; }
@SuppressWarnings("rawtypes") @Override public boolean enterLiteralNode(final LiteralNode literalNode) { if (literalNode instanceof LiteralNode.PrimitiveLiteralNode) { weight += CONST_WEIGHT; return false; } weight += LITERAL_WEIGHT; if (literalNode instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode; final Node[] value = arrayLiteralNode.getValue(); final int[] postsets = arrayLiteralNode.getPostsets(); final List<Splittable.SplitRange> units = arrayLiteralNode.getSplitRanges(); if (units == null) { for (final int postset : postsets) { weight += AASTORE_WEIGHT; final Node element = value[postset]; if (element != null) { element.accept(this); } } } return false; } return true; }
@Override protected LiteralNode<?> eval() { final Node rhsNode = parent.getExpression(); if (!(rhsNode instanceof LiteralNode)) { return null; } if (rhsNode instanceof ArrayLiteralNode) { return null; } final LiteralNode<?> rhs = (LiteralNode<?>)rhsNode; final Type rhsType = rhs.getType(); final boolean rhsInteger = rhsType.isInteger() || rhsType.isBoolean(); LiteralNode<?> literalNode; switch (parent.tokenType()) { case ADD: if (rhsInteger) { literalNode = LiteralNode.newInstance(token, finish, rhs.getInt32()); } else { literalNode = LiteralNode.newInstance(token, finish, rhs.getNumber()); } break; case SUB: if (rhsInteger && rhs.getInt32() != 0) { // @see test/script/basic/minuszero.js literalNode = LiteralNode.newInstance(token, finish, -rhs.getInt32()); } else { literalNode = LiteralNode.newInstance(token, finish, -rhs.getNumber()); } break; case NOT: literalNode = LiteralNode.newInstance(token, finish, !rhs.getBoolean()); break; case BIT_NOT: literalNode = LiteralNode.newInstance(token, finish, ~rhs.getInt32()); break; default: return null; } return literalNode; }
private void loadLiteral(final LiteralNode<?> node, final TypeBounds resultBounds) { final Object value = node.getValue(); if (value == null) { method.loadNull(); } else if (value instanceof Undefined) { method.loadUndefined(resultBounds.within(Type.OBJECT)); } else if (value instanceof String) { final String string = (String)value; if (string.length() > MethodEmitter.LARGE_STRING_THRESHOLD / 3) { // 3 == max bytes per encoded char loadConstant(string); } else { method.load(string); } } else if (value instanceof RegexToken) { loadRegex((RegexToken)value); } else if (value instanceof Boolean) { method.load((Boolean)value); } else if (value instanceof Integer) { if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) { method.load((Integer)value); method.convert(Type.OBJECT); } else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) { method.load(((Integer)value).doubleValue()); } else if(!resultBounds.canBeNarrowerThan(Type.LONG)) { method.load(((Integer)value).longValue()); } else { method.load((Integer)value); } } else if (value instanceof Long) { if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) { method.load((Long)value); method.convert(Type.OBJECT); } else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) { method.load(((Long)value).doubleValue()); } else { method.load((Long)value); } } else if (value instanceof Double) { if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) { method.load((Double)value); method.convert(Type.OBJECT); } else { method.load((Double)value); } } else if (node instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteral = (ArrayLiteralNode)node; final ArrayType atype = arrayLiteral.getArrayType(); loadArray(arrayLiteral, atype); globalAllocateArray(atype); } else { throw new UnsupportedOperationException("Unknown literal for " + node.getClass() + " " + value.getClass() + " " + value); } }
@Override protected LiteralNode<?> eval() { final Node rhsNode = parent.getExpression(); if (!(rhsNode instanceof LiteralNode)) { return null; } if (rhsNode instanceof ArrayLiteralNode) { return null; } final LiteralNode<?> rhs = (LiteralNode<?>)rhsNode; final Type rhsType = rhs.getType(); final boolean rhsInteger = rhsType.isInteger() || rhsType.isBoolean(); LiteralNode<?> literalNode; switch (parent.tokenType()) { case POS: if (rhsInteger) { literalNode = LiteralNode.newInstance(token, finish, rhs.getInt32()); } else if (rhsType.isLong()) { literalNode = LiteralNode.newInstance(token, finish, rhs.getLong()); } else { literalNode = LiteralNode.newInstance(token, finish, rhs.getNumber()); } break; case NEG: if (rhsInteger && rhs.getInt32() != 0) { // @see test/script/basic/minuszero.js literalNode = LiteralNode.newInstance(token, finish, -rhs.getInt32()); } else if (rhsType.isLong() && rhs.getLong() != 0L) { literalNode = LiteralNode.newInstance(token, finish, -rhs.getLong()); } else { literalNode = LiteralNode.newInstance(token, finish, -rhs.getNumber()); } break; case NOT: literalNode = LiteralNode.newInstance(token, finish, !rhs.getBoolean()); break; case BIT_NOT: literalNode = LiteralNode.newInstance(token, finish, ~rhs.getInt32()); break; default: return null; } return literalNode; }
private void loadLiteral(final LiteralNode<?> node, final TypeBounds resultBounds) { final Object value = node.getValue(); if (value == null) { method.loadNull(); } else if (value instanceof Undefined) { method.loadUndefined(resultBounds.within(Type.OBJECT)); } else if (value instanceof String) { final String string = (String)value; if (string.length() > MethodEmitter.LARGE_STRING_THRESHOLD / 3) { // 3 == max bytes per encoded char loadConstant(string); } else { method.load(string); } } else if (value instanceof RegexToken) { loadRegex((RegexToken)value); } else if (value instanceof Boolean) { method.load((Boolean)value); } else if (value instanceof Integer) { if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) { method.load((Integer)value); method.convert(Type.OBJECT); } else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) { method.load(((Integer)value).doubleValue()); } else { method.load((Integer)value); } } else if (value instanceof Double) { if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) { method.load((Double)value); method.convert(Type.OBJECT); } else { method.load((Double)value); } } else if (node instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteral = (ArrayLiteralNode)node; final ArrayType atype = arrayLiteral.getArrayType(); loadArray(arrayLiteral, atype); globalAllocateArray(atype); } else { throw new UnsupportedOperationException("Unknown literal for " + node.getClass() + " " + value.getClass() + " " + value); } }
@Override protected LiteralNode<?> eval() { final Node rhsNode = parent.getExpression(); if (!(rhsNode instanceof LiteralNode)) { return null; } if (rhsNode instanceof ArrayLiteralNode) { return null; } final LiteralNode<?> rhs = (LiteralNode<?>)rhsNode; final Type rhsType = rhs.getType(); final boolean rhsInteger = rhsType.isInteger() || rhsType.isBoolean(); LiteralNode<?> literalNode; switch (parent.tokenType()) { case ADD: if (rhsInteger) { literalNode = LiteralNode.newInstance(token, finish, rhs.getInt32()); } else if (rhsType.isLong()) { literalNode = LiteralNode.newInstance(token, finish, rhs.getLong()); } else { literalNode = LiteralNode.newInstance(token, finish, rhs.getNumber()); } break; case SUB: if (rhsInteger && rhs.getInt32() != 0) { // @see test/script/basic/minuszero.js literalNode = LiteralNode.newInstance(token, finish, -rhs.getInt32()); } else if (rhsType.isLong() && rhs.getLong() != 0L) { literalNode = LiteralNode.newInstance(token, finish, -rhs.getLong()); } else { literalNode = LiteralNode.newInstance(token, finish, -rhs.getNumber()); } break; case NOT: literalNode = LiteralNode.newInstance(token, finish, !rhs.getBoolean()); break; case BIT_NOT: literalNode = LiteralNode.newInstance(token, finish, ~rhs.getInt32()); break; default: return null; } return literalNode; }