Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix relative paths in wasm backend source maps. Fixes #9837 #9882

Merged
merged 17 commits into from
Nov 27, 2019
6 changes: 3 additions & 3 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7188,7 +7188,7 @@ def encode_utf8(data):
# the output file.
self.assertPathsIdentical(map_referent, data['file'])
assert len(data['sources']) == 1, data['sources']
self.assertPathsIdentical(os.path.abspath('src.cpp'), data['sources'][0])
self.assertPathsIdentical('src.cpp', data['sources'][0])
if hasattr(data, 'sourcesContent'):
# the sourcesContent attribute is optional, but if it is present it
# needs to containt valid source text.
Expand All @@ -7201,7 +7201,7 @@ def encode_utf8(data):
mappings = encode_utf8(mappings)
seen_lines = set()
for m in mappings:
self.assertPathsIdentical(os.path.abspath('src.cpp'), m['source'])
self.assertPathsIdentical('src.cpp', m['source'])
seen_lines.add(m['originalLine'])
# ensure that all the 'meaningful' lines in the original code get mapped
# when optimizing, the binaryen optimizer may remove some of them (by inlining, etc.)
Expand Down Expand Up @@ -8241,7 +8241,7 @@ def test_ubsan_full_static_cast(self, args):
'g4': ('-g4', [
"src.cpp:3:12: runtime error: reference binding to null pointer of type 'int'",
'in main ',
'/src.cpp:3:8'
'src.cpp:3:8'
]),
})
@no_fastcomp('ubsan not supported on fastcomp')
Expand Down
21 changes: 21 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -8916,6 +8916,27 @@ def test_wasm_sourcemap_dead(self):
# has only two entries
self.assertRegexpMatches(output, r'"mappings":\s*"[A-Za-z0-9+/]+,[A-Za-z0-9+/]+"')

def test_wasm_sourcemap_relative_paths(self):
def test(infile, source_map_added_dir=''):
expected_source_map_path = os.path.join(source_map_added_dir, 'a.cpp')
print(infile, expected_source_map_path)
RReverser marked this conversation as resolved.
Show resolved Hide resolved
shutil.copyfile(path_from_root('tests', 'hello_123.c'), infile)
infiles = [
infile,
os.path.abspath(infile),
'./' + infile
]
for curr in infiles:
print(' ', curr)
run_process([PYTHON, EMCC, curr, '-g4'])
with open('a.out.wasm.map', 'r') as f:
self.assertIn('"%s"' % expected_source_map_path, str(f.read()))

test('a.cpp')

os.mkdir('inner')
test(os.path.join('inner', 'a.cpp'), 'inner')

def test_wasm_producers_section(self):
# no producers section by default
run_process([PYTHON, EMCC, path_from_root('tests', 'hello_world.c')])
Expand Down
6 changes: 5 additions & 1 deletion tools/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -2871,10 +2871,14 @@ def path_to_system_js_libraries(library_name):

@staticmethod
def emit_wasm_source_map(wasm_file, map_file):
# source file paths must be relative to the location of the map (which is
# emitted alongside the wasm)
base_path = os.path.dirname(os.path.abspath(Settings.WASM_BINARY_FILE))
RReverser marked this conversation as resolved.
Show resolved Hide resolved
sourcemap_cmd = [PYTHON, path_from_root('tools', 'wasm-sourcemap.py'),
wasm_file,
'--dwarfdump=' + LLVM_DWARFDUMP,
'-o', map_file]
'-o', map_file,
'--basepath=' + base_path]
check_call(sourcemap_cmd)

@staticmethod
Expand Down
8 changes: 4 additions & 4 deletions tools/wasm-sourcemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def parse_args():
parser.add_argument('-u', '--source-map-url', nargs='?', help='specifies sourceMappingURL section contest')
parser.add_argument('--dwarfdump', help="path to llvm-dwarfdump executable")
parser.add_argument('--dwarfdump-output', nargs='?', help=argparse.SUPPRESS)
parser.add_argument('--basepath', help='base path for source files, which will be relative to this')
return parser.parse_args()


Expand Down Expand Up @@ -243,11 +244,10 @@ def read_dwarf_entries(wasm, options):
return sorted(entries, key=lambda entry: entry['address'])


def build_sourcemap(entries, code_section_offset, prefixes, collect_sources):
def build_sourcemap(entries, code_section_offset, prefixes, collect_sources, base_path):
sources = []
sources_content = [] if collect_sources else None
mappings = []

sources_map = {}
last_address = 0
last_source_id = 0
Expand All @@ -263,7 +263,7 @@ def build_sourcemap(entries, code_section_offset, prefixes, collect_sources):
if column == 0:
column = 1
address = entry['address'] + code_section_offset
file_name = entry['file']
file_name = os.path.relpath(os.path.abspath(entry['file']), base_path)
source_name = prefixes.sources.resolve(file_name)
if source_name not in sources_map:
source_id = len(sources)
Expand Down Expand Up @@ -311,7 +311,7 @@ def main():
prefixes = SourceMapPrefixes(sources=Prefixes(options.prefix), load=Prefixes(options.load_prefix))

logger.debug('Saving to %s' % options.output)
map = build_sourcemap(entries, code_section_offset, prefixes, options.sources)
map = build_sourcemap(entries, code_section_offset, prefixes, options.sources, options.basepath)
with open(options.output, 'w') as outfile:
json.dump(map, outfile, separators=(',', ':'))

Expand Down