• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

i-net-software / JWebAssembly / 523

pending completion
523

push

travis-ci-com

Horcrux7
remove debug code

5870 of 6747 relevant lines covered (87.0%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.24
/src/de/inetsoftware/jwebassembly/JWebAssembly.java
1
/*
2
 * Copyright 2017 - 2022 Volker Berlin (i-net software)
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package de.inetsoftware.jwebassembly;
17

18
import java.io.BufferedInputStream;
19
import java.io.ByteArrayOutputStream;
20
import java.io.File;
21
import java.io.IOException;
22
import java.io.OutputStream;
23
import java.io.PrintWriter;
24
import java.io.StringWriter;
25
import java.net.MalformedURLException;
26
import java.net.URL;
27
import java.security.ProtectionDomain;
28
import java.util.ArrayList;
29
import java.util.HashMap;
30
import java.util.List;
31
import java.util.logging.Formatter;
32
import java.util.logging.Level;
33
import java.util.logging.LogRecord;
34
import java.util.logging.Logger;
35
import java.util.logging.StreamHandler;
36

37
import javax.annotation.Nonnull;
38

39
import de.inetsoftware.classparser.ClassFile;
40
import de.inetsoftware.jwebassembly.binary.BinaryModuleWriter;
41
import de.inetsoftware.jwebassembly.module.ModuleGenerator;
42
import de.inetsoftware.jwebassembly.module.ModuleWriter;
43
import de.inetsoftware.jwebassembly.module.WasmOptions;
44
import de.inetsoftware.jwebassembly.module.WasmTarget;
45
import de.inetsoftware.jwebassembly.text.TextModuleWriter;
46

47
/**
48
 * The main class of the compiler.
49
 * 
50
 * @author Volker Berlin
51
 */
52
public class JWebAssembly {
53

54
    private final List<URL>               classFiles = new ArrayList<>();
1✔
55

56
    private final HashMap<String, String> properties = new HashMap<>();
1✔
57

58
    private final List<URL>               libraries  = new ArrayList<>();
1✔
59

60
    /**
61
     * Property for adding debug names to the output if true.
62
     */
63
    public static final String DEBUG_NAMES = "DebugNames";
64

65
    /**
66
     * Property for relative path between the final wasm file location and the source files location for the source map.
67
     * If not empty it should end with a slash like "../../src/main/java/".
68
     */
69
    public static final String SOURCE_MAP_BASE = "SourceMapBase";
70

71
    /**
72
     * The name of the annotation for import functions.
73
     */
74
    public static final String IMPORT_ANNOTATION = "de.inetsoftware.jwebassembly.api.annotation.Import";
75

76
    /**
77
     * The name of the annotation for export functions.
78
     */
79
    public static final String EXPORT_ANNOTATION =  "de.inetsoftware.jwebassembly.api.annotation.Export";
80

81
    /**
82
     * The name of the annotation for native WASM code in text format. 
83
     */
84
    public static final String TEXTCODE_ANNOTATION =  "de.inetsoftware.jwebassembly.api.annotation.WasmTextCode";
85

86
    /**
87
     * The name of the annotation for replacing a single method of the Java runtime. 
88
     */
89
    public static final String REPLACE_ANNOTATION =  "de.inetsoftware.jwebassembly.api.annotation.Replace";
90

91
    /**
92
     * The name of the annotation for partial class another class of the Java runtime. 
93
     */
94
    public static final String PARTIAL_ANNOTATION =  "de.inetsoftware.jwebassembly.api.annotation.Partial";
95

96
    /**
97
     * If the GC feature of WASM should be use or the GC of the JavaScript host. If true use the GC instructions of WASM.
98
     */
99
    public static final String WASM_USE_GC = "wasm.use_gc";
100

101
    /**
102
     * If the exception handling feature of WASM should be use or an unreachable instruction. If true use the exception instructions of WASM.
103
     */
104
    public static final String WASM_USE_EH = "wasm.use_eh";
105

106
    /**
107
     * Compiler property to ignore all referenced native methods without declared replacement in a library and replace them with a stub that throws an exception at runtime.
108
     */
109
    public static final String IGNORE_NATIVE = "IgnoreNative";
110

111
    /**
112
     * The logger instance
113
     */
114
    public static final Logger LOGGER = Logger.getAnonymousLogger( null );
1✔
115
    static {
116
        LOGGER.setUseParentHandlers( false );
1✔
117
        Formatter formatter = new Formatter() {
1✔
118
            @Override
119
            public String format( LogRecord record ) {
120
                String msg = record.getMessage() + '\n';
×
121
                if( record.getThrown() != null ) {
×
122
                    StringWriter sw = new StringWriter();
×
123
                    PrintWriter pw = new PrintWriter( sw );
×
124
                    record.getThrown().printStackTrace( pw );
×
125
                    pw.close();
×
126
                    msg += sw.toString();
×
127
                }
128
                return msg;
×
129
            }
130
        };
131
        StreamHandler handler = new StreamHandler( System.out, formatter ) {
1✔
132
            @Override
133
            public void publish(LogRecord record) {
134
                super.publish(record);
×
135
                flush();
×
136
            }
×
137
        };
138
        handler.setLevel( Level.ALL );
1✔
139
        LOGGER.addHandler( handler );
1✔
140
        //LOGGER.setLevel( Level.FINE );
141
    }
1✔
142

143
    /**
144
     * Create a instance.
145
     */
146
    public JWebAssembly() {
1✔
147
        ProtectionDomain protectionDomain = getClass().getProtectionDomain();
1✔
148
        if( protectionDomain != null ) {
1✔
149
            libraries.add( protectionDomain.getCodeSource().getLocation() ); // add the compiler self to the library path
1✔
150
        }
151
    }
1✔
152

153
    /**
154
     * Add a classFile to compile
155
     * 
156
     * @param classFile
157
     *            the file
158
     */
159
    public void addFile( @Nonnull File classFile ) {
160
        try {
161
            classFiles.add( classFile.toURI().toURL() );
1✔
162
        } catch( MalformedURLException ex ) {
×
163
            throw new IllegalArgumentException( ex );
×
164
        }
1✔
165
    }
1✔
166

167
    /**
168
     * Add a classFile to compile
169
     * 
170
     * @param classFile
171
     *            the file
172
     */
173
    public void addFile( @Nonnull URL classFile ) {
174
        classFiles.add( classFile );
1✔
175
    }
1✔
176

177
    /**
178
     * Set property to control the behavior of the compiler
179
     * 
180
     * @param key
181
     *            the key
182
     * @param value
183
     *            the new value
184
     */
185
    public void setProperty( String key, String value ) {
186
        properties.put( key, value );
1✔
187
    }
1✔
188

189
    /**
190
     * Get the value of a property.
191
     * 
192
     * @param key
193
     *            the key
194
     * @return the current value
195
     */
196
    public String getProperty( String key ) {
197
        return properties.get( key );
1✔
198
    }
199

200
    /**
201
     * Add a jar or zip file as library to the compiler. Methods from the library will be add to the wasm only when used.
202
     * 
203
     * @param library
204
     *            a archive file
205
     */
206
    public void addLibrary( @Nonnull File library ) {
207
        try {
208
            addLibrary( library.toURI().toURL() );
1✔
209
        } catch( MalformedURLException ex ) {
×
210
            throw new IllegalArgumentException( ex );
×
211
        }
1✔
212
    }
1✔
213

214
    /**
215
     * Add a jar or zip file as library to the compiler. Methods from the library will be add to the wasm only when used.
216
     * 
217
     * @param library
218
     *            a archive file
219
     */
220
    public void addLibrary( @Nonnull URL library ) {
221
        libraries.add( library );
1✔
222
    }
1✔
223

224
     /**
225
     * Convert the added files to a WebAssembly module in text representation.
226
     * 
227
     * @return the module as string
228
     * @throws WasmException
229
     *             if any conversion error occurs
230
     */
231
    public String compileToText() throws WasmException {
232
        StringBuilder output = new StringBuilder();
1✔
233
        try {
234
            compileToText( output );
1✔
235
            return output.toString();
1✔
236
        } catch( Exception ex ) {
×
237
            System.err.println( output );
×
238
            throw ex;
×
239
        }
240
    }
241

242
    /**
243
     * Convert the added files to a WebAssembly module in text representation.
244
     * 
245
     * @param file
246
     *            the target for the module data
247
     * @throws WasmException
248
     *             if any conversion error occurs
249
     */
250
    public void compileToText( File file ) throws WasmException {
251
        try (WasmTarget target = new WasmTarget( file )) {
1✔
252
            compileToText( target );
1✔
253
        } catch( Exception ex ) {
1✔
254
            throw WasmException.create( ex );
1✔
255
        }
1✔
256
    }
1✔
257

258
    /**
259
     * Convert the added files to a WebAssembly module in text representation.
260
     * 
261
     * @param output
262
     *            the target for the module data
263
     * @throws WasmException
264
     *             if any conversion error occurs
265
     */
266
    public void compileToText( Appendable output ) throws WasmException {
267
        try (WasmTarget target = new WasmTarget( output )) {
1✔
268
            compileToText( target );
1✔
269
        } catch( Exception ex ) {
×
270
            throw WasmException.create( ex );
×
271
        }
1✔
272
    }
1✔
273

274
    /**
275
     * Convert the added files to a WebAssembly module in text representation.
276
     * 
277
     * @param target
278
     *            the target for the module data
279
     * @throws WasmException
280
     *             if any conversion error occurs
281
     */
282
    private void compileToText( WasmTarget target ) throws WasmException {
283
        try (TextModuleWriter writer = new TextModuleWriter( target, new WasmOptions( properties ) )) {
1✔
284
            compile( writer, target );
1✔
285
        } catch( Exception ex ) {
1✔
286
            throw WasmException.create( ex );
1✔
287
        }
1✔
288
    }
1✔
289

290
    /**
291
     * Convert the added files to a WebAssembly module in binary representation.
292
     * 
293
     * @return the module as string
294
     * @throws WasmException
295
     *             if any conversion error occurs
296
     */
297
    public byte[] compileToBinary() throws WasmException {
298
        ByteArrayOutputStream output = new ByteArrayOutputStream();
1✔
299
        compileToBinary( output );
1✔
300
        return output.toByteArray();
1✔
301
    }
302

303
    /**
304
     * Convert the added files to a WebAssembly module in binary representation.
305
     * 
306
     * @param file
307
     *            the target for the module data
308
     * @throws WasmException
309
     *             if any conversion error occurs
310
     */
311
    public void compileToBinary( File file ) throws WasmException {
312
        try (WasmTarget target = new WasmTarget( file ) ) {
1✔
313
            compileToBinary( target );
1✔
314
        } catch( Exception ex ) {
1✔
315
            throw WasmException.create( ex );
1✔
316
        }
1✔
317
    }
1✔
318

319
    /**
320
     * Convert the added files to a WebAssembly module in binary representation.
321
     * 
322
     * @param output
323
     *            the target for the module data
324
     * @throws WasmException
325
     *             if any conversion error occurs
326
     */
327
    public void compileToBinary( OutputStream output ) throws WasmException {
328
        try (WasmTarget target = new WasmTarget( output )) {
1✔
329
            compileToBinary( target );
1✔
330
        } catch( Exception ex ) {
1✔
331
            throw WasmException.create( ex );
1✔
332
        }
1✔
333
    }
1✔
334

335
    /**
336
     * Convert the added files to a WebAssembly module in binary representation.
337
     * 
338
     * @param target
339
     *            the target for the module data
340
     * @throws WasmException
341
     *             if any conversion error occurs
342
     */
343
    private void compileToBinary( WasmTarget target ) throws WasmException {
344
        try (BinaryModuleWriter writer = new BinaryModuleWriter( target, new WasmOptions( properties ) )) {
1✔
345
            compile( writer, target );
1✔
346
        } catch( Exception ex ) {
1✔
347
            throw WasmException.create( ex );
1✔
348
        }
1✔
349
    }
1✔
350

351
    /**
352
     * Convert the added files to a WebAssembly module.
353
     * 
354
     * @param writer
355
     *            the formatter
356
     * @param target
357
     *            the target for the module data
358
     * @throws IOException
359
     *             if any I/O error occur
360
     * @throws WasmException
361
     *             if any conversion error occurs
362
     */
363
    private void compile( ModuleWriter writer, WasmTarget target ) throws IOException, WasmException {
364
        ModuleGenerator generator = new ModuleGenerator( writer, target, libraries );
1✔
365
        for( URL url : classFiles ) {
1✔
366
            try {
367
                ClassFile classFile = new ClassFile( new BufferedInputStream( url.openStream() ) );
1✔
368
                generator.prepare( classFile );
1✔
369
            } catch( IOException ex ) {
×
370
                LOGGER.fine( url + " " + ex );
×
371
                if( url.getFile().endsWith( ".class" ) ) {
×
372
                    throw WasmException.create( "Parsing of file " + url + " failed.", ex );
×
373
                }
374
                // does not throw an exception on non *.class files like resource files or *.kotlin_module
375
            }
1✔
376
        }
1✔
377
        generator.prepareFinish();
1✔
378
        generator.finish();
1✔
379
    }
1✔
380
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc