Project

Profile

Help

Revision 75ea2cf1

Added by Michael Kay about 3 years ago

Fix bug #4046: bytecode for reloaded SEF files

View differences:

latest9.9/hej/net/sf/saxon/expr/instruct/AnalyzeString.java
45 45

  
46 46
    private RegularExpression pattern;
47 47

  
48
    private boolean useXsltErrorCodes = true;
49

  
50 48
    /**
51 49
     * Construct an AnalyzeString instruction
52 50
     *
......
148 146
        return pattern;
149 147
    }
150 148

  
151
    /**
152
     * @return if allow XSLT 3.0 features
153
     */
154
    public boolean isAllow30features() {
155
        return true;
156
    }
157

  
158 149
    /**
159 150
     * Ask whether common subexpressions found in the operands of this expression can
160 151
     * be extracted and evaluated outside the expression itself. The result is irrelevant
......
168 159
        return false;
169 160
    }
170 161

  
171
    /**
172
     * Say whether the expression should return the error codes for the fn:analyze-string function
173
     * or the xsl:analyze-string instruction
174
     *
175
     * @param xslt if true use the error codes for  xsl:analyze-string, otherwise use the error codes for fn:analyze-string
176
     */
177
    public void setUseXsltErrorCodes(boolean xslt) {
178
        useXsltErrorCodes = xslt;
179
    }
180

  
181
    /**
182
     * Ask whether the expression should return the error codes for the fn:analyze-string function
183
     * or the xsl:analyze-string instruction
184
     *
185
     * @return true if using the error codes for  xsl:analyze-string, otherwise use the error codes for fn:analyze-string
186
     */
187

  
188
    public boolean isUseXsltErrorCodes() {
189
        return useXsltErrorCodes;
190
    }
191

  
192 162
    /*@NotNull*/
193 163
    public Expression typeCheck(ExpressionVisitor visitor, ContextItemStaticInfo contextInfo) throws XPathException {
194 164

  
......
236 206
            nonMatchingOp.optimize(visitor, config.makeContextItemStaticInfo(BuiltInAtomicType.STRING, false));
237 207
        }
238 208

  
209
        List<String> warnings = new ArrayList<>();
210
        precomputeRegex(config, warnings);
211
        for (String w : warnings) {
212
            visitor.getStaticContext().issueWarning(w, getLocation());
213
        }
214

  
215
        return this;
216
    }
217

  
218
    public void precomputeRegex(Configuration config, List<String> warnings) throws XPathException {
239 219
        if (pattern == null && getRegex() instanceof StringLiteral && getFlags() instanceof StringLiteral) {
240 220
            try {
241 221
                final CharSequence regex = ((StringLiteral) this.getRegex()).getStringValue();
242 222
                final CharSequence flagstr = ((StringLiteral) getFlags()).getStringValue();
243 223

  
244 224
                String hostLang = "XP30";
245
                List<String> warnings = new ArrayList<>();
246 225
                pattern = config.compileRegularExpression(regex, flagstr.toString(), hostLang, warnings);
247
                for (String w : warnings) {
248
                    visitor.getStaticContext().issueWarning(w, getLocation());
249
                }
250 226

  
251
                if ((!isAllow30features() || !useXsltErrorCodes) && pattern.matches("")) {
252
                    // prevent it being reported more than once
253
                    pattern = config.compileRegularExpression("x", "", "XP20", warnings);
254
                    invalidRegex("The regular expression must not be one that matches a zero-length string",
255
                            useXsltErrorCodes ? "XTDE1150" : "FORX0003");
256
                }
257 227
            } catch (XPathException err) {
258 228
                if ("XTDE1150".equals(err.getErrorCodeLocalPart())) {
259 229
                    throw err;
260 230
                }
261 231
                if ("FORX0001".equals(err.getErrorCodeLocalPart())) {
262
                    invalidRegex("Error in regular expression flags: " + err, useXsltErrorCodes ? "XTDE1145" : "FORX0001");
232
                    invalidRegex("Error in regular expression flags: " + err, "FORX0001");
263 233
                } else {
264
                    invalidRegex("Error in regular expression: " + err, useXsltErrorCodes ? "XTDE1140" : err.getErrorCodeLocalPart());
234
                    invalidRegex("Error in regular expression: " + err, err.getErrorCodeLocalPart());
265 235
                }
266 236
            }
267 237
        }
268
        return this;
269 238
    }
270 239

  
271 240
    private void invalidRegex(String message, String errorCode) throws XPathException {
......
419 388
        RegularExpression re = pattern;
420 389
        if (re == null) {
421 390
            String flagstr = getFlags().evaluateAsString(context).toString();
422
            String dialect = "XP30";
423 391
            StringValue regexString = (StringValue)getRegex().evaluateItem(context);
424 392
            re = context.getConfiguration().compileRegularExpression(
425
                        getRegex().evaluateAsString(context), flagstr, dialect, null);
426
            if ((dialect.equals("XP20") || !useXsltErrorCodes) && re.matches("")) {
427
                dynamicError("The regular expression must not be one that matches a zero-length string",
428
                        useXsltErrorCodes ? "XTDE1150" : "FORX0003", context);
429
            }
393
                        getRegex().evaluateAsString(context), flagstr, "XP30", null);
430 394
        }
431 395

  
432 396
        return re.analyze(input);
......
456 420
        c2.setCurrentRegexIterator(iter);
457 421

  
458 422
        AnalyzeMappingFunction fn = new AnalyzeMappingFunction(iter, c2, getNonMatching(), getMatching());
459
        return new ContextMappingIterator(fn, c2);
423
        return new ContextMappingIterator<>(fn, c2);
460 424
    }
461 425

  
462 426
    /**
latest9.9/hej/net/sf/saxon/style/XSLFunction.java
365 365
        top.indexFunction(decl);
366 366
    }
367 367

  
368
    /**
369
     * Notify all references to this function of the data type.
370
     *
371
     * @throws XPathException
372
     */
373

  
374
    public void fixupReferences() throws XPathException {
375
//        for (UserFunctionReference reference : references) {
376
//            if (reference instanceof UserFunctionCall) {
377
//                ((UserFunctionCall) reference).setStaticType(resultType);
378
//            }
379
//        }
380
        super.fixupReferences();
381
    }
382

  
383 368
    public void validate(ComponentDeclaration decl) throws XPathException {
384 369

  
385 370
        stackFrameMap = getConfiguration().makeSlotManager();
......
401 386
     * all references to the function to the executable representation
402 387
     * (a UserFunction object)
403 388
     *
404
     * @throws XPathException
389
     * @throws XPathException if compilation fails
405 390
     */
406 391

  
407 392
    public void compileDeclaration(Compilation compilation, ComponentDeclaration decl) throws XPathException {
latest9.9/hej/net/sf/saxon/trans/PackageLoaderHE.java
405 405
                NodeInfo grandchild = child.iterateAxis(AxisInfo.CHILD, NodeKindTest.ELEMENT).next();
406 406
                Actor cc = null;
407 407
                String kind = grandchild.getLocalPart();
408
                boolean codeGen = false;
408 409
                switch (kind) {
409 410
                    case "template":
410 411
                        cc = readNamedTemplate(grandchild);
412
                        codeGen = true;
411 413
                        break;
412 414
                    case "globalVariable":
413 415
                        cc = readGlobalVariable(grandchild);
416
                        codeGen = true;
414 417
                        break;
415 418
                    case "globalParam":
416 419
                        cc = readGlobalParam(grandchild);
417 420
                        break;
418 421
                    case "function":
419 422
                        cc = readGlobalFunction(grandchild);
423
                        codeGen = ((UserFunction)cc).getDeclaredStreamability() == FunctionStreamability.UNCLASSIFIED;
420 424
                        break;
421 425
                    case "mode":
422 426
                        cc = readMode(grandchild);
......
430 434
                component = Component.makeComponent(cc, vis, pack, declaringPackage);
431 435
                cc.setDeclaringComponent(component);
432 436
                cc.setDeclaredVisibility(vis);
437
                Optimizer optimizer = config.obtainOptimizer();
438
                StructuredQName name = cc.getObjectName();
439
                if (codeGen) {
440
                    String objectName = name == null ? ("h" + component.hashCode()) : name.getLocalPart();
441
                    cc.setBody(optimizer.makeByteCodeCandidate(cc, cc.getBody(), objectName, 0));
442
                    optimizer.injectByteCodeCandidates(cc.getBody());
443
                } else if (cc instanceof Mode) {
444
                    ((Mode)cc).processRules(rule -> {
445
                        TemplateRule tr = (TemplateRule)rule.getAction();
446
                        String objectName = "match=\"" + tr.getMatchPattern() + '"';
447
                        tr.setBody(optimizer.makeByteCodeCandidate(tr, tr.getBody(), objectName, 0));
448
                        optimizer.injectByteCodeCandidates(tr.getBody());
449
                    });
450
                }
433 451
            }
434 452
            externalReferences.put(component, binds);
435 453
            componentIdMap.put(id, component);
......
586 604
        } else if (flags.contains("d")) {
587 605
            function.setDeterminism(UserFunction.Determinism.DETERMINISTIC);
588 606
        }
607
        // Ignore the "m" flag - handled in subclass for Saxon-PE
589 608

  
590 609
        boolean streaming = false;
591 610
        if (flags.contains("U")) {
......
622 641
            arg.setVariableQName(getQNameAttribute(argElement, "name"));
623 642
            arg.setRequiredType(parseSequenceType(argElement, "as"));
624 643
            params.add(arg);
625
            // TOOD: additional attributes inlineable etc
644
            // TODO: additional attributes inlineable etc
626 645
            localBindings.push(arg);
627 646
        }
628 647
        function.setParameterDefinitions(params.toArray(new UserFunctionParameter[0]));
......
1417 1436
            Expression flags = loader.getExpressionWithRole(element, "flags");
1418 1437
            Expression matching = loader.getExpressionWithRole(element, "matching");
1419 1438
            Expression nonMatching = loader.getExpressionWithRole(element, "nonMatching");
1420
            return new AnalyzeString(select, regex, flags, matching, nonMatching, null);
1439
            AnalyzeString instr = new AnalyzeString(select, regex, flags, matching, nonMatching, null);
1440
            instr.precomputeRegex(loader.getConfiguration(), null);
1441
            return instr;
1421 1442
        });
1422 1443

  
1423 1444
        eMap.put("and", (loader, element) -> {

Also available in: Unified diff