@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 Node leaveObjectNode(final ObjectNode objectNode) { final List<Splittable.SplitRange> ranges = objectNode.getSplitRanges(); if (ranges != null) { final List<Splittable.SplitRange> newRanges = new ArrayList<>(); for (final Splittable.SplitRange range : ranges) { newRanges.add(new Splittable.SplitRange(getExistingReplacement(range), range.getLow(), range.getHigh())); } return objectNode.setSplitRanges(lc, newRanges); } return super.leaveObjectNode(objectNode); }
@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; }
private static boolean isSplitLiteral(final LexicalContextNode expr) { return expr instanceof Splittable && ((Splittable) expr).getSplitRanges() != null; }
private void loadSplitLiteral(final SplitLiteralCreator creator, final List<Splittable.SplitRange> ranges, final Type literalType) { assert ranges != null; // final Type literalType = Type.typeFor(literalClass); final MethodEmitter savedMethod = method; final FunctionNode currentFunction = lc.getCurrentFunction(); for (final Splittable.SplitRange splitRange : ranges) { unit = lc.pushCompileUnit(splitRange.getCompileUnit()); assert unit != null; final String className = unit.getUnitClassName(); final String name = currentFunction.uniqueName(SPLIT_PREFIX.symbolName()); final Class<?> clazz = literalType.getTypeClass(); final String signature = methodDescriptor(clazz, ScriptFunction.class, Object.class, ScriptObject.class, clazz); pushMethodEmitter(unit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature)); method.setFunctionNode(currentFunction); method.begin(); defineCommonSplitMethodParameters(); defineSplitMethodParameter(CompilerConstants.SPLIT_ARRAY_ARG.slot(), literalType); // NOTE: when this is no longer needed, SplitIntoFunctions will no longer have to add IS_SPLIT // to synthetic functions, and FunctionNode.needsCallee() will no longer need to test for isSplit(). final int literalSlot = fixScopeSlot(currentFunction, 3); lc.enterSplitNode(); creator.populateRange(method, literalType, literalSlot, splitRange.getLow(), splitRange.getHigh()); method._return(); lc.exitSplitNode(); method.end(); lc.releaseSlots(); popMethodEmitter(); assert method == savedMethod; method.loadCompilerConstant(CALLEE).swap(); method.loadCompilerConstant(THIS).swap(); method.loadCompilerConstant(SCOPE).swap(); method.invokestatic(className, name, signature); unit = lc.popCompileUnit(unit); } }