nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Source.java
author sundar
Fri, 03 Jul 2015 18:41:58 +0530
changeset 31546 c1ae3f297a28
parent 30974 b7c26088b58c
child 31549 b627094c5649
permissions -rw-r--r--
8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not Reviewed-by: attila, lagergren, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import java.io.ByteArrayOutputStream;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import java.io.File;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    30
import java.io.FileNotFoundException;
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
    31
import java.io.FileOutputStream;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import java.io.IOError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import java.io.IOException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import java.io.InputStream;
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
    35
import java.io.PrintWriter;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import java.io.Reader;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    37
import java.lang.ref.WeakReference;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import java.net.MalformedURLException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
import java.net.URISyntaxException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import java.net.URL;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    41
import java.net.URLConnection;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import java.nio.charset.Charset;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import java.nio.charset.StandardCharsets;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import java.nio.file.Files;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import java.nio.file.Path;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
import java.nio.file.Paths;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
    47
import java.security.MessageDigest;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
    48
import java.security.NoSuchAlgorithmException;
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
    49
import java.time.LocalDateTime;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
import java.util.Arrays;
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
    51
import java.util.Base64;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import java.util.Objects;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    53
import java.util.WeakHashMap;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    54
import jdk.nashorn.api.scripting.URLReader;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import jdk.nashorn.internal.parser.Token;
24769
attila
parents: 24206
diff changeset
    56
import jdk.nashorn.internal.runtime.logging.DebugLogger;
attila
parents: 24206
diff changeset
    57
import jdk.nashorn.internal.runtime.logging.Loggable;
attila
parents: 24206
diff changeset
    58
import jdk.nashorn.internal.runtime.logging.Logger;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
 * Source objects track the origin of JavaScript entities.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    61
 */
24769
attila
parents: 24206
diff changeset
    62
@Logger(name="source")
attila
parents: 24206
diff changeset
    63
public final class Source implements Loggable {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    64
    private static final int BUF_SIZE = 8 * 1024;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    65
    private static final Cache CACHE = new Cache();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    66
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
    67
    // Message digest to file name encoder
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
    68
    private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding();
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
    69
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
     * Descriptive name of the source as supplied by the user. Used for error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
     * reporting to the user. For example, SyntaxError will use this to print message.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
     * Used to implement __FILE__. Also used for SourceFile in .class for debugger usage.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
    private final String name;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
     * Base directory the File or base part of the URL. Used to implement __DIR__.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
     * Used to load scripts relative to the 'directory' or 'base' URL of current script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
     * This will be null when it can't be computed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
    private final String base;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    84
    /** Source content */
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    85
    private final Data data;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    86
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
    /** Cached hash code */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
    private int hash;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
    90
    /** Base64-encoded SHA1 digest of this source object */
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
    91
    private volatile byte[] digest;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
    92
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    93
    /** source URL set via //@ sourceURL or //# sourceURL directive */
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    94
    private String explicitURL;
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    95
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    96
    // Do *not* make this public, ever! Trusts the URL and content.
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    97
    private Source(final String name, final String base, final Data data) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    98
        this.name = name;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    99
        this.base = base;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   100
        this.data = data;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   101
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   102
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   103
    private static synchronized Source sourceFor(final String name, final String base, final URLData data) throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   104
        try {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   105
            final Source newSource = new Source(name, base, data);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   106
            final Source existingSource = CACHE.get(newSource);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   107
            if (existingSource != null) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   108
                // Force any access errors
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   109
                data.checkPermissionAndClose();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   110
                return existingSource;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   111
            }
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   112
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   113
            // All sources in cache must be fully loaded
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   114
            data.load();
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   115
            CACHE.put(newSource, newSource);
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   116
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   117
            return newSource;
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   118
        } catch (final RuntimeException e) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   119
            final Throwable cause = e.getCause();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   120
            if (cause instanceof IOException) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   121
                throw (IOException) cause;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   122
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   123
            throw e;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   124
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   125
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   126
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   127
    private static class Cache extends WeakHashMap<Source, WeakReference<Source>> {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   128
        public Source get(final Source key) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   129
            final WeakReference<Source> ref = super.get(key);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   130
            return ref == null ? null : ref.get();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   131
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   132
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   133
        public void put(final Source key, final Source value) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   134
            assert !(value.data instanceof RawData);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   135
            put(key, new WeakReference<>(value));
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   136
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   137
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   138
24881
67cf2d94e00a 8044798: API for debugging Nashorn
sundar
parents: 24778
diff changeset
   139
    /* package-private */
67cf2d94e00a 8044798: API for debugging Nashorn
sundar
parents: 24778
diff changeset
   140
    DebuggerSupport.SourceInfo getSourceInfo() {
67cf2d94e00a 8044798: API for debugging Nashorn
sundar
parents: 24778
diff changeset
   141
        return new DebuggerSupport.SourceInfo(getName(), data.hashCode(),  data.url(), data.array());
67cf2d94e00a 8044798: API for debugging Nashorn
sundar
parents: 24778
diff changeset
   142
    }
67cf2d94e00a 8044798: API for debugging Nashorn
sundar
parents: 24778
diff changeset
   143
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   144
    // Wrapper to manage lazy loading
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   145
    private static interface Data {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   146
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   147
        URL url();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   148
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   149
        int length();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   150
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   151
        long lastModified();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   152
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   153
        char[] array();
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   154
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   155
        boolean isEvalCode();
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   156
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   157
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   158
    private static class RawData implements Data {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   159
        private final char[] array;
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   160
        private final boolean evalCode;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   161
        private int hash;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   162
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   163
        private RawData(final char[] array, final boolean evalCode) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   164
            this.array = Objects.requireNonNull(array);
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   165
            this.evalCode = evalCode;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   166
        }
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   167
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   168
        private RawData(final String source, final boolean evalCode) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   169
            this.array = Objects.requireNonNull(source).toCharArray();
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   170
            this.evalCode = evalCode;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   171
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   172
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   173
        private RawData(final Reader reader) throws IOException {
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   174
            this(readFully(reader), false);
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   175
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   176
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   177
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   178
        public int hashCode() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   179
            int h = hash;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   180
            if (h == 0) {
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   181
                h = hash = Arrays.hashCode(array) ^ (evalCode? 1 : 0);
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   182
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   183
            return h;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   184
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   185
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   186
        @Override
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   187
        public boolean equals(final Object obj) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   188
            if (this == obj) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   189
                return true;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   190
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   191
            if (obj instanceof RawData) {
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   192
                final RawData other = (RawData)obj;
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   193
                return Arrays.equals(array, other.array) && evalCode == other.evalCode;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   194
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   195
            return false;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   196
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   197
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   198
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   199
        public String toString() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   200
            return new String(array());
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   201
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   202
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   203
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   204
        public URL url() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   205
            return null;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   206
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   207
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   208
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   209
        public int length() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   210
            return array.length;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   211
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   212
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   213
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   214
        public long lastModified() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   215
            return 0;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   216
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   217
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   218
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   219
        public char[] array() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   220
            return array;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   221
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   222
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   223
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   224
        @Override
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   225
        public boolean isEvalCode() {
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   226
            return evalCode;
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   227
        }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   228
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   229
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   230
    private static class URLData implements Data {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   231
        private final URL url;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   232
        protected final Charset cs;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   233
        private int hash;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   234
        protected char[] array;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   235
        protected int length;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   236
        protected long lastModified;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   237
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   238
        private URLData(final URL url, final Charset cs) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   239
            this.url = Objects.requireNonNull(url);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   240
            this.cs = cs;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   241
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   243
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   244
        public int hashCode() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   245
            int h = hash;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   246
            if (h == 0) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   247
                h = hash = url.hashCode();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   248
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   249
            return h;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   250
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   251
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   252
        @Override
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   253
        public boolean equals(final Object other) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   254
            if (this == other) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   255
                return true;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   256
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   257
            if (!(other instanceof URLData)) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   258
                return false;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   259
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   260
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   261
            final URLData otherData = (URLData) other;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   262
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   263
            if (url.equals(otherData.url)) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   264
                // Make sure both have meta data loaded
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   265
                try {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   266
                    if (isDeferred()) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   267
                        // Data in cache is always loaded, and we only compare to cached data.
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   268
                        assert !otherData.isDeferred();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   269
                        loadMeta();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   270
                    } else if (otherData.isDeferred()) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   271
                        otherData.loadMeta();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   272
                    }
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   273
                } catch (final IOException e) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   274
                    throw new RuntimeException(e);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   275
                }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   276
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   277
                // Compare meta data
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   278
                return this.length == otherData.length && this.lastModified == otherData.lastModified;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   279
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   280
            return false;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   281
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   282
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   283
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   284
        public String toString() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   285
            return new String(array());
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   286
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   287
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   288
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   289
        public URL url() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   290
            return url;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   291
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   292
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   293
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   294
        public int length() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   295
            return length;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   296
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   297
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   298
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   299
        public long lastModified() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   300
            return lastModified;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   301
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   302
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   303
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   304
        public char[] array() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   305
            assert !isDeferred();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   306
            return array;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   307
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   308
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   309
        @Override
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   310
        public boolean isEvalCode() {
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   311
            return false;
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   312
        }
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   313
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   314
        boolean isDeferred() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   315
            return array == null;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   316
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   317
25250
b5a4e0ac31d1 8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents: 25240
diff changeset
   318
        @SuppressWarnings("try")
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   319
        protected void checkPermissionAndClose() throws IOException {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   320
            try (InputStream in = url.openStream()) {
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   321
                // empty
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   322
            }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   323
            debug("permission checked for ", url);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   324
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   325
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   326
        protected void load() throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   327
            if (array == null) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   328
                final URLConnection c = url.openConnection();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   329
                try (InputStream in = c.getInputStream()) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   330
                    array = cs == null ? readFully(in) : readFully(in, cs);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   331
                    length = array.length;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   332
                    lastModified = c.getLastModified();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   333
                    debug("loaded content for ", url);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   334
                }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   335
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   336
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   337
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   338
        protected void loadMeta() throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   339
            if (length == 0 && lastModified == 0) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   340
                final URLConnection c = url.openConnection();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   341
                length = c.getContentLength();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   342
                lastModified = c.getLastModified();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   343
                debug("loaded metadata for ", url);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   344
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   345
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   346
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   347
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   348
    private static class FileData extends URLData {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   349
        private final File file;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   350
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   351
        private FileData(final File file, final Charset cs) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   352
            super(getURLFromFile(file), cs);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   353
            this.file = file;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   354
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   355
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   356
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   357
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   358
        protected void checkPermissionAndClose() throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   359
            if (!file.canRead()) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   360
                throw new FileNotFoundException(file + " (Permission Denied)");
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   361
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   362
            debug("permission checked for ", file);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   363
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   364
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   365
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   366
        protected void loadMeta() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   367
            if (length == 0 && lastModified == 0) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   368
                length = (int) file.length();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   369
                lastModified = file.lastModified();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   370
                debug("loaded metadata for ", file);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   371
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   372
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   373
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   374
        @Override
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   375
        protected void load() throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   376
            if (array == null) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   377
                array = cs == null ? readFully(file) : readFully(file, cs);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   378
                length = array.length;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   379
                lastModified = file.lastModified();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   380
                debug("loaded content for ", file);
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   381
            }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   382
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   383
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   384
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   385
    private static void debug(final Object... msg) {
24769
attila
parents: 24206
diff changeset
   386
        final DebugLogger logger = getLoggerStatic();
attila
parents: 24206
diff changeset
   387
        if (logger != null) {
attila
parents: 24206
diff changeset
   388
            logger.info(msg);
attila
parents: 24206
diff changeset
   389
        }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   390
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   391
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   392
    private char[] data() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   393
        return data.array();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   394
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   395
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   396
    /**
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   397
     * Returns a Source instance
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   399
     * @param name    source name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
     * @param content contents as char array
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   401
     * @param isEval does this represent code from 'eval' call?
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   402
     * @return source instance
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   403
     */
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   404
    public static Source sourceFor(final String name, final char[] content, final boolean isEval) {
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   405
        return new Source(name, baseName(name), new RawData(content, isEval));
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   406
    }
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   407
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   408
    /**
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   409
     * Returns a Source instance
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   410
     *
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   411
     * @param name    source name
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   412
     * @param content contents as char array
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   413
     *
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   414
     * @return source instance
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
     */
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   416
    public static Source sourceFor(final String name, final char[] content) {
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   417
        return sourceFor(name, content, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
    /**
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   421
     * Returns a Source instance
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
     * @param name    source name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
     * @param content contents as string
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   425
     * @param isEval does this represent code from 'eval' call?
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   426
     * @return source instance
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   427
     */
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   428
    public static Source sourceFor(final String name, final String content, final boolean isEval) {
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   429
        return new Source(name, baseName(name), new RawData(content, isEval));
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   430
    }
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   431
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   432
    /**
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   433
     * Returns a Source instance
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   434
     *
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   435
     * @param name    source name
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   436
     * @param content contents as string
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   437
     * @return source instance
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
     */
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   439
    public static Source sourceFor(final String name, final String content) {
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   440
        return sourceFor(name, content, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   441
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
     * @param name  source name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
     * @param url   url from which source can be loaded
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
     *
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   449
     * @return source instance
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   450
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
     * @throws IOException if source cannot be loaded
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
     */
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   453
    public static Source sourceFor(final String name, final URL url) throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   454
        return sourceFor(name, url, null);
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   455
    }
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   456
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   457
    /**
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   458
     * Constructor
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   459
     *
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   460
     * @param name  source name
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   461
     * @param url   url from which source can be loaded
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   462
     * @param cs    Charset used to convert bytes to chars
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   463
     *
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   464
     * @return source instance
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   465
     *
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   466
     * @throws IOException if source cannot be loaded
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   467
     */
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   468
    public static Source sourceFor(final String name, final URL url, final Charset cs) throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   469
        return sourceFor(name, baseURL(url), new URLData(url, cs));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   472
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   473
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
     * @param name  source name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
     * @param file  file from which source can be loaded
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
     *
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   478
     * @return source instance
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   479
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
     * @throws IOException if source cannot be loaded
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
     */
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   482
    public static Source sourceFor(final String name, final File file) throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   483
        return sourceFor(name, file, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   484
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   486
    /**
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   487
     * Constructor
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   488
     *
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   489
     * @param name  source name
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   490
     * @param path  path from which source can be loaded
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   491
     *
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   492
     * @return source instance
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   493
     *
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   494
     * @throws IOException if source cannot be loaded
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   495
     */
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   496
    public static Source sourceFor(final String name, final Path path) throws IOException {
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   497
        File file = null;
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   498
        try {
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   499
            file = path.toFile();
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   500
        } catch (final UnsupportedOperationException uoe) {
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   501
        }
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   502
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   503
        if (file != null) {
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   504
            return sourceFor(name, file);
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   505
        } else {
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   506
            return sourceFor(name, Files.newBufferedReader(path));
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   507
        }
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   508
    }
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   509
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   510
    /**
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   511
     * Constructor
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   512
     *
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   513
     * @param name  source name
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   514
     * @param file  file from which source can be loaded
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   515
     * @param cs    Charset used to convert bytes to chars
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   516
     *
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   517
     * @return source instance
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   518
     *
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   519
     * @throws IOException if source cannot be loaded
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   520
     */
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   521
    public static Source sourceFor(final String name, final File file, final Charset cs) throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   522
        final File absFile = file.getAbsoluteFile();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   523
        return sourceFor(name, dirName(absFile, null), new FileData(file, cs));
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   524
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   525
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   526
    /**
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   527
     * Returns an instance
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   528
     *
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   529
     * @param name source name
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   530
     * @param reader reader from which source can be loaded
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   531
     *
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   532
     * @return source instance
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   533
     *
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   534
     * @throws IOException if source cannot be loaded
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   535
     */
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   536
    public static Source sourceFor(final String name, final Reader reader) throws IOException {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   537
        // Extract URL from URLReader to defer loading and reuse cached data if available.
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   538
        if (reader instanceof URLReader) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   539
            final URLReader urlReader = (URLReader) reader;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   540
            return sourceFor(name, urlReader.getURL(), urlReader.getCharset());
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   541
        }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   542
        return new Source(name, baseName(name), new RawData(reader));
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   543
    }
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   544
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
    public boolean equals(final Object obj) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   547
        if (this == obj) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   548
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
        if (!(obj instanceof Source)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   551
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   552
        }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   553
        final Source other = (Source) obj;
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   554
        return Objects.equals(name, other.name) && data.equals(other.data);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   555
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   556
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   557
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   558
    public int hashCode() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   559
        int h = hash;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   560
        if (h == 0) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   561
            h = hash = data.hashCode() ^ Objects.hashCode(name);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   562
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   563
        return h;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   564
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   565
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   566
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
     * Fetch source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   568
     * @return Source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   569
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   570
    public String getString() {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   571
        return data.toString();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   572
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   573
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
     * Get the user supplied name of this script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   576
     * @return User supplied source name.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   578
    public String getName() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   579
        return name;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   580
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   581
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   582
    /**
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   583
     * Get the last modified time of this script.
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   584
     * @return Last modified time.
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   585
     */
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   586
    public long getLastModified() {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   587
        return data.lastModified();
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   588
    }
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   589
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   590
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   591
     * Get the "directory" part of the file or "base" of the URL.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   592
     * @return base of file or URL.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
    public String getBase() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
        return base;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
     * Fetch a portion of source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
     * @param start start index in source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
     * @param len length of portion
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   602
     * @return Source content portion.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   604
    public String getString(final int start, final int len) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   605
        return new String(data(), start, len);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   606
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   607
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   608
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   609
     * Fetch a portion of source content associated with a token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   610
     * @param token Token descriptor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   611
     * @return Source content portion.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   612
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   613
    public String getString(final long token) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   614
        final int start = Token.descPosition(token);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   615
        final int len = Token.descLength(token);
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   616
        return new String(data(), start, len);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   617
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
    /**
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   620
     * Returns the source URL of this script Source. Can be null if Source
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   621
     * was created from a String or a char[].
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   622
     *
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   623
     * @return URL source or null
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   624
     */
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   625
    public URL getURL() {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   626
        return data.url();
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   627
    }
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   628
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   629
    /**
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   630
     * Get explicit source URL.
29407
3fd4ede1581e 8074671: Nashorn Parser API
sundar
parents: 26249
diff changeset
   631
     * @return URL set via sourceURL directive
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   632
     */
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   633
    public String getExplicitURL() {
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   634
        return explicitURL;
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   635
    }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   636
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   637
    /**
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   638
     * Set explicit source URL.
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   639
     * @param explicitURL URL set via sourceURL directive
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   640
     */
26067
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26055
diff changeset
   641
    public void setExplicitURL(final String explicitURL) {
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   642
        this.explicitURL = explicitURL;
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   643
    }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   644
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   645
    /**
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   646
     * Returns whether this source was submitted via 'eval' call or not.
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   647
     *
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   648
     * @return true if this source represents code submitted via 'eval'
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   649
     */
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   650
    public boolean isEvalCode() {
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   651
        return data.isEvalCode();
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   652
    }
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   653
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   654
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   655
     * Find the beginning of the line containing position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   656
     * @param position Index to offending token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
     * @return Index of first character of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   658
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   659
    private int findBOLN(final int position) {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   660
        final char[] d = data();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
        for (int i = position - 1; i > 0; i--) {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   662
            final char ch = d[i];
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   663
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   664
            if (ch == '\n' || ch == '\r') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   665
                return i + 1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   666
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   667
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   668
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   669
        return 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   670
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   671
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
     * Find the end of the line containing position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   674
     * @param position Index to offending token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   675
     * @return Index of last character of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   677
    private int findEOLN(final int position) {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   678
        final char[] d = data();
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   679
        final int length = d.length;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   680
        for (int i = position; i < length; i++) {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   681
            final char ch = d[i];
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   682
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   683
            if (ch == '\n' || ch == '\r') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   684
                return i - 1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   685
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   686
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   687
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   688
        return length - 1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   689
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   690
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   691
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   692
     * Return line number of character position.
20559
9244eb6d195b 8025515: Performance issues with Source.getLine()
hannesw
parents: 20210
diff changeset
   693
     *
9244eb6d195b 8025515: Performance issues with Source.getLine()
hannesw
parents: 20210
diff changeset
   694
     * <p>This method can be expensive for large sources as it iterates through
9244eb6d195b 8025515: Performance issues with Source.getLine()
hannesw
parents: 20210
diff changeset
   695
     * all characters up to {@code position}.</p>
9244eb6d195b 8025515: Performance issues with Source.getLine()
hannesw
parents: 20210
diff changeset
   696
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
     * @param position Position of character in source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
     * @return Line number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   699
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   700
    public int getLine(final int position) {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   701
        final char[] d = data();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
        // Line count starts at 1.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   703
        int line = 1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   704
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   705
        for (int i = 0; i < position; i++) {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24881
diff changeset
   706
            final char ch = d[i];
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   707
            // Works for both \n and \r\n.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   708
            if (ch == '\n') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
                line++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   710
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
        return line;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
     * Return column number of character position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
     * @param position Position of character in source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
     * @return Column number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
    public int getColumn(final int position) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
        // TODO - column needs to account for tabs.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
        return position - findBOLN(position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   724
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   727
     * Return line text including character position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   728
     * @param position Position of character in source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
     * @return Line text.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
    public String getSourceLine(final int position) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   732
        // Find end of previous line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
        final int first = findBOLN(position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
        // Find end of this line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   735
        final int last = findEOLN(position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   736
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   737
        return new String(data(), first, last - first + 1);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   738
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   739
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   740
    /**
26249
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   741
     * Get the content of this source as a char array. Note that the underlying array is returned instead of a
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   742
     * clone; modifying the char array will cause modification to the source; this should not be done. While
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   743
     * there is an apparent danger that we allow unfettered access to an underlying mutable array, the
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   744
     * {@code Source} class is in a restricted {@code jdk.nashorn.internal.*} package and as such it is
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   745
     * inaccessible by external actors in an environment with a security manager. Returning a clone would be
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   746
     * detrimental to performance.
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   747
     * @return content the content of this source as a char array
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   748
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   749
    public char[] getContent() {
26249
5fbbd38ebc5b 8056052: Source.getContent() does excess Object.clone()
attila
parents: 26068
diff changeset
   750
        return data();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   751
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   752
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   753
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   754
     * Get the length in chars for this source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   755
     * @return length
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   756
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   757
    public int getLength() {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   758
        return data.length();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   759
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   760
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   761
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   762
     * Read all of the source until end of file. Return it as char array
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   763
     *
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   764
     * @param reader reader opened to source stream
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   765
     * @return source as content
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   766
     * @throws IOException if source could not be read
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   767
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   768
    public static char[] readFully(final Reader reader) throws IOException {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   769
        final char[]        arr = new char[BUF_SIZE];
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   770
        final StringBuilder sb  = new StringBuilder();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   771
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   772
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   773
            int numChars;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   774
            while ((numChars = reader.read(arr, 0, arr.length)) > 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   775
                sb.append(arr, 0, numChars);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   776
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   777
        } finally {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   778
            reader.close();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   779
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   780
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   781
        return sb.toString().toCharArray();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   782
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   783
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   784
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   785
     * Read all of the source until end of file. Return it as char array
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   786
     *
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   787
     * @param file source file
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
     * @return source as content
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   789
     * @throws IOException if source could not be read
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   790
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   791
    public static char[] readFully(final File file) throws IOException {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   792
        if (!file.isFile()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   793
            throw new IOException(file + " is not a file"); //TODO localize?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   794
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   795
        return byteToCharArray(Files.readAllBytes(file.toPath()));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   796
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   797
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   798
    /**
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   799
     * Read all of the source until end of file. Return it as char array
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   800
     *
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   801
     * @param file source file
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   802
     * @param cs Charset used to convert bytes to chars
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   803
     * @return source as content
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   804
     * @throws IOException if source could not be read
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   805
     */
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   806
    public static char[] readFully(final File file, final Charset cs) throws IOException {
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   807
        if (!file.isFile()) {
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   808
            throw new IOException(file + " is not a file"); //TODO localize?
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   809
        }
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   810
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   811
        final byte[] buf = Files.readAllBytes(file.toPath());
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   812
        return (cs != null) ? new String(buf, cs).toCharArray() : byteToCharArray(buf);
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   813
    }
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   814
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   815
    /**
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   816
     * Read all of the source until end of stream from the given URL. Return it as char array
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   817
     *
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   818
     * @param url URL to read content from
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   819
     * @return source as content
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   820
     * @throws IOException if source could not be read
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   821
     */
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   822
    public static char[] readFully(final URL url) throws IOException {
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   823
        return readFully(url.openStream());
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   824
    }
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   825
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   826
    /**
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   827
     * Read all of the source until end of file. Return it as char array
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   828
     *
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   829
     * @param url URL to read content from
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   830
     * @param cs Charset used to convert bytes to chars
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   831
     * @return source as content
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   832
     * @throws IOException if source could not be read
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   833
     */
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   834
    public static char[] readFully(final URL url, final Charset cs) throws IOException {
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   835
        return readFully(url.openStream(), cs);
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   836
    }
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   837
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   838
    /**
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   839
     * Get a Base64-encoded SHA1 digest for this source.
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   840
     *
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   841
     * @return a Base64-encoded SHA1 digest for this source
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   842
     */
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   843
    public String getDigest() {
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   844
        return new String(getDigestBytes(), StandardCharsets.US_ASCII);
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   845
    }
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   846
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   847
    private byte[] getDigestBytes() {
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   848
        byte[] ldigest = digest;
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   849
        if (ldigest == null) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   850
            final char[] content = data();
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   851
            final byte[] bytes = new byte[content.length * 2];
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   852
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   853
            for (int i = 0; i < content.length; i++) {
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   854
                bytes[i * 2]     = (byte)  (content[i] & 0x00ff);
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   855
                bytes[i * 2 + 1] = (byte) ((content[i] & 0xff00) >> 8);
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   856
            }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   857
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   858
            try {
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   859
                final MessageDigest md = MessageDigest.getInstance("SHA-1");
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   860
                if (name != null) {
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   861
                    md.update(name.getBytes(StandardCharsets.UTF_8));
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   862
                }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   863
                if (base != null) {
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   864
                    md.update(base.getBytes(StandardCharsets.UTF_8));
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   865
                }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   866
                if (getURL() != null) {
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   867
                    md.update(getURL().toString().getBytes(StandardCharsets.UTF_8));
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   868
                }
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   869
                digest = ldigest = BASE64.encode(md.digest(bytes));
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   870
            } catch (final NoSuchAlgorithmException e) {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   871
                throw new RuntimeException(e);
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   872
            }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   873
        }
25255
cf56cdc2c663 8049225: Source class exposes public mutable array
attila
parents: 25250
diff changeset
   874
        return ldigest;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   875
    }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   876
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 20559
diff changeset
   877
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   878
     * Get the base url. This is currently used for testing only
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   879
     * @param url a URL
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   880
     * @return base URL for url
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   881
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   882
    public static String baseURL(final URL url) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   883
        if (url.getProtocol().equals("file")) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   884
            try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   885
                final Path path = Paths.get(url.toURI());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   886
                final Path parent = path.getParent();
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   887
                return (parent != null) ? (parent + File.separator) : null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   888
            } catch (final SecurityException | URISyntaxException | IOError e) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   889
                return null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   890
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   891
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   892
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   893
        // FIXME: is there a better way to find 'base' URL of a given URL?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   894
        String path = url.getPath();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   895
        if (path.isEmpty()) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   896
            return null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   897
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   898
        path = path.substring(0, path.lastIndexOf('/') + 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
        final int port = url.getPort();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   900
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   901
            return new URL(url.getProtocol(), url.getHost(), port, path).toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   902
        } catch (final MalformedURLException e) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   903
            return null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   904
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   905
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   906
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   907
    private static String dirName(final File file, final String DEFAULT_BASE_NAME) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   908
        final String res = file.getParent();
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   909
        return (res != null) ? (res + File.separator) : DEFAULT_BASE_NAME;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   910
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   911
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   912
    // fake directory like name
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   913
    private static String baseName(final String name) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   914
        int idx = name.lastIndexOf('/');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   915
        if (idx == -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   916
            idx = name.lastIndexOf('\\');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   917
        }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   918
        return (idx != -1) ? name.substring(0, idx + 1) : null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   919
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   920
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   921
    private static char[] readFully(final InputStream is, final Charset cs) throws IOException {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   922
        return (cs != null) ? new String(readBytes(is), cs).toCharArray() : readFully(is);
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   923
    }
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 16241
diff changeset
   924
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   925
    private static char[] readFully(final InputStream is) throws IOException {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   926
        return byteToCharArray(readBytes(is));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   927
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   928
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
    private static char[] byteToCharArray(final byte[] bytes) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   930
        Charset cs = StandardCharsets.UTF_8;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   931
        int start = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   932
        // BOM detection.
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   933
        if (bytes.length > 1 && bytes[0] == (byte) 0xFE && bytes[1] == (byte) 0xFF) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   934
            start = 2;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   935
            cs = StandardCharsets.UTF_16BE;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   936
        } else if (bytes.length > 1 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE) {
30974
b7c26088b58c 8066218: UTF-32LE mistakenly detected as UTF-16LE
attila
parents: 30513
diff changeset
   937
            if (bytes.length > 3 && bytes[2] == 0 && bytes[3] == 0) {
b7c26088b58c 8066218: UTF-32LE mistakenly detected as UTF-16LE
attila
parents: 30513
diff changeset
   938
                start = 4;
b7c26088b58c 8066218: UTF-32LE mistakenly detected as UTF-16LE
attila
parents: 30513
diff changeset
   939
                cs = Charset.forName("UTF-32LE");
b7c26088b58c 8066218: UTF-32LE mistakenly detected as UTF-16LE
attila
parents: 30513
diff changeset
   940
            } else {
b7c26088b58c 8066218: UTF-32LE mistakenly detected as UTF-16LE
attila
parents: 30513
diff changeset
   941
                start = 2;
b7c26088b58c 8066218: UTF-32LE mistakenly detected as UTF-16LE
attila
parents: 30513
diff changeset
   942
                cs = StandardCharsets.UTF_16LE;
b7c26088b58c 8066218: UTF-32LE mistakenly detected as UTF-16LE
attila
parents: 30513
diff changeset
   943
            }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   944
        } else if (bytes.length > 2 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   945
            start = 3;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
            cs = StandardCharsets.UTF_8;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   947
        } else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte) 0xFE && bytes[3] == (byte) 0xFF) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   948
            start = 4;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   949
            cs = Charset.forName("UTF-32BE");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   950
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   951
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   952
        return new String(bytes, start, bytes.length - start, cs).toCharArray();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   953
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   954
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   955
    static byte[] readBytes(final InputStream is) throws IOException {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   956
        final byte[] arr = new byte[BUF_SIZE];
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   957
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   958
            try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   959
                int numBytes;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   960
                while ((numBytes = is.read(arr, 0, arr.length)) > 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   961
                    buf.write(arr, 0, numBytes);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   962
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   963
                return buf.toByteArray();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   964
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   965
        } finally {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   966
            is.close();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   967
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   968
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   969
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   970
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   971
    public String toString() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   972
        return getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   973
    }
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   974
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   975
    private static URL getURLFromFile(final File file) {
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   976
        try {
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   977
            return file.toURI().toURL();
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   978
        } catch (final SecurityException | MalformedURLException ignored) {
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   979
            return null;
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   980
        }
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16151
diff changeset
   981
    }
24769
attila
parents: 24206
diff changeset
   982
attila
parents: 24206
diff changeset
   983
    private static DebugLogger getLoggerStatic() {
attila
parents: 24206
diff changeset
   984
        final Context context = Context.getContextTrustedOrNull();
attila
parents: 24206
diff changeset
   985
        return context == null ? null : context.getLogger(Source.class);
attila
parents: 24206
diff changeset
   986
    }
attila
parents: 24206
diff changeset
   987
attila
parents: 24206
diff changeset
   988
    @Override
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24769
diff changeset
   989
    public DebugLogger initLogger(final Context context) {
24769
attila
parents: 24206
diff changeset
   990
        return context.getLogger(this.getClass());
attila
parents: 24206
diff changeset
   991
    }
attila
parents: 24206
diff changeset
   992
attila
parents: 24206
diff changeset
   993
    @Override
attila
parents: 24206
diff changeset
   994
    public DebugLogger getLogger() {
attila
parents: 24206
diff changeset
   995
        return initLogger(Context.getContextTrusted());
attila
parents: 24206
diff changeset
   996
    }
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
   997
31546
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
   998
    private File dumpFile(final File dirFile) {
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
   999
        final URL u = getURL();
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1000
        final StringBuilder buf = new StringBuilder();
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1001
        // make it unique by prefixing current date & time
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1002
        buf.append(LocalDateTime.now().toString());
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1003
        buf.append('_');
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1004
        if (u != null) {
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1005
            // make it a safe file name
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1006
            buf.append(u.toString()
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1007
                    .replace('/', '_')
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1008
                    .replace('\\', '_'));
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1009
        } else {
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1010
            buf.append(getName());
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1011
        }
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1012
31546
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1013
        return new File(dirFile, buf.toString());
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1014
    }
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1015
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1016
    void dump(final String dir) {
31546
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1017
        final File dirFile = new File(dir);
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1018
        final File file = dumpFile(dirFile);
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1019
        if (!dirFile.exists() && !dirFile.mkdirs()) {
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1020
            debug("Skipping source dump for " + name);
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1021
            return;
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1022
        }
c1ae3f297a28 8130424: if directory specified with --dest-dir does not exist, only .class files are dumped and .js files are not
sundar
parents: 30974
diff changeset
  1023
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1024
        try (final FileOutputStream fos = new FileOutputStream(file)) {
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1025
            final PrintWriter pw = new PrintWriter(fos);
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1026
            pw.print(data.toString());
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1027
            pw.flush();
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1028
        } catch (final IOException ioExp) {
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1029
            debug("Skipping source dump for " +
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1030
                    name +
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1031
                    ": " +
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1032
                    ECMAErrors.getMessage(
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1033
                        "io.error.cant.write",
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1034
                        dir.toString() +
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1035
                        " : " + ioExp.toString()));
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1036
        }
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 29407
diff changeset
  1037
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1038
}