File: | out/../deps/v8/src/wasm/wasm-module-sourcemap.cc |
Warning: | line 147, column 10 Although the value stored to 'qnt' is used in the enclosing expression, the value is never actually read from 'qnt' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | // Copyright 2019 the V8 project authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #include "src/wasm/wasm-module-sourcemap.h" |
6 | |
7 | #include <algorithm> |
8 | |
9 | #include "include/v8-context.h" |
10 | #include "include/v8-json.h" |
11 | #include "include/v8-local-handle.h" |
12 | #include "include/v8-object.h" |
13 | #include "include/v8-primitive.h" |
14 | #include "src/api/api.h" |
15 | #include "src/base/vlq-base64.h" |
16 | |
17 | namespace v8 { |
18 | |
19 | class String; |
20 | |
21 | namespace internal { |
22 | namespace wasm { |
23 | |
24 | WasmModuleSourceMap::WasmModuleSourceMap(v8::Isolate* v8_isolate, |
25 | v8::Local<v8::String> src_map_str) { |
26 | v8::HandleScope scope(v8_isolate); |
27 | v8::Local<v8::Context> context = v8::Context::New(v8_isolate); |
28 | |
29 | v8::Local<v8::Value> src_map_value; |
30 | if (!v8::JSON::Parse(context, src_map_str).ToLocal(&src_map_value)) return; |
31 | v8::Local<v8::Object> src_map_obj = |
32 | v8::Local<v8::Object>::Cast(src_map_value); |
33 | |
34 | v8::Local<v8::Value> version_value, sources_value, mappings_value; |
35 | bool has_valid_version = |
36 | src_map_obj |
37 | ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "version")) |
38 | .ToLocal(&version_value) && |
39 | version_value->IsUint32(); |
40 | uint32_t version = 0; |
41 | if (!has_valid_version || !version_value->Uint32Value(context).To(&version) || |
42 | version != 3u) |
43 | return; |
44 | |
45 | bool has_valid_sources = |
46 | src_map_obj |
47 | ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "sources")) |
48 | .ToLocal(&sources_value) && |
49 | sources_value->IsArray(); |
50 | if (!has_valid_sources) return; |
51 | |
52 | v8::Local<v8::Object> sources_arr = |
53 | v8::Local<v8::Object>::Cast(sources_value); |
54 | v8::Local<v8::Value> sources_len_value; |
55 | if (!sources_arr |
56 | ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "length")) |
57 | .ToLocal(&sources_len_value)) |
58 | return; |
59 | uint32_t sources_len = 0; |
60 | if (!sources_len_value->Uint32Value(context).To(&sources_len)) return; |
61 | |
62 | for (uint32_t i = 0; i < sources_len; ++i) { |
63 | v8::Local<v8::Value> file_name_value; |
64 | if (!sources_arr->Get(context, i).ToLocal(&file_name_value) || |
65 | !file_name_value->IsString()) |
66 | return; |
67 | v8::Local<v8::String> file_name = |
68 | v8::Local<v8::String>::Cast(file_name_value); |
69 | auto file_name_sz = file_name->Utf8Length(v8_isolate); |
70 | std::unique_ptr<char[]> file_name_buf(new char[file_name_sz + 1]); |
71 | file_name->WriteUtf8(v8_isolate, file_name_buf.get()); |
72 | file_name_buf.get()[file_name_sz] = '\0'; |
73 | filenames.emplace_back(file_name_buf.get()); |
74 | } |
75 | |
76 | bool has_valid_mappings = |
77 | src_map_obj |
78 | ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "mappings")) |
79 | .ToLocal(&mappings_value) && |
80 | mappings_value->IsString(); |
81 | if (!has_valid_mappings) return; |
82 | |
83 | v8::Local<v8::String> mappings = v8::Local<v8::String>::Cast(mappings_value); |
84 | int mappings_sz = mappings->Utf8Length(v8_isolate); |
85 | std::unique_ptr<char[]> mappings_buf(new char[mappings_sz + 1]); |
86 | mappings->WriteUtf8(v8_isolate, mappings_buf.get()); |
87 | mappings_buf.get()[mappings_sz] = '\0'; |
88 | |
89 | valid_ = DecodeMapping(mappings_buf.get()); |
90 | } |
91 | |
92 | size_t WasmModuleSourceMap::GetSourceLine(size_t wasm_offset) const { |
93 | std::vector<std::size_t>::const_iterator up = |
94 | std::upper_bound(offsets.begin(), offsets.end(), wasm_offset); |
95 | CHECK_NE(offsets.begin(), up)do { bool _cmp = ::v8::base::CmpNEImpl< typename ::v8::base ::pass_value_or_ref<decltype(offsets.begin())>::type, typename ::v8::base::pass_value_or_ref<decltype(up)>::type>( (offsets.begin()), (up)); do { if ((__builtin_expect(!!(!(_cmp )), 0))) { V8_Fatal("Check failed: %s.", "offsets.begin()" " " "!=" " " "up"); } } while (false); } while (false); |
96 | size_t source_idx = up - offsets.begin() - 1; |
97 | return source_row[source_idx]; |
98 | } |
99 | |
100 | std::string WasmModuleSourceMap::GetFilename(size_t wasm_offset) const { |
101 | std::vector<size_t>::const_iterator up = |
102 | std::upper_bound(offsets.begin(), offsets.end(), wasm_offset); |
103 | CHECK_NE(offsets.begin(), up)do { bool _cmp = ::v8::base::CmpNEImpl< typename ::v8::base ::pass_value_or_ref<decltype(offsets.begin())>::type, typename ::v8::base::pass_value_or_ref<decltype(up)>::type>( (offsets.begin()), (up)); do { if ((__builtin_expect(!!(!(_cmp )), 0))) { V8_Fatal("Check failed: %s.", "offsets.begin()" " " "!=" " " "up"); } } while (false); } while (false); |
104 | size_t offset_idx = up - offsets.begin() - 1; |
105 | size_t filename_idx = file_idxs[offset_idx]; |
106 | return filenames[filename_idx]; |
107 | } |
108 | |
109 | bool WasmModuleSourceMap::HasSource(size_t start, size_t end) const { |
110 | return start <= *(offsets.end() - 1) && end > *offsets.begin(); |
111 | } |
112 | |
113 | bool WasmModuleSourceMap::HasValidEntry(size_t start, size_t addr) const { |
114 | std::vector<size_t>::const_iterator up = |
115 | std::upper_bound(offsets.begin(), offsets.end(), addr); |
116 | if (up == offsets.begin()) return false; |
117 | size_t offset_idx = up - offsets.begin() - 1; |
118 | size_t entry_offset = offsets[offset_idx]; |
119 | if (entry_offset < start) return false; |
120 | return true; |
121 | } |
122 | |
123 | bool WasmModuleSourceMap::DecodeMapping(const std::string& s) { |
124 | size_t pos = 0, gen_col = 0, file_idx = 0, ori_line = 0; |
125 | int32_t qnt = 0; |
126 | |
127 | while (pos < s.size()) { |
128 | // Skip redundant commas. |
129 | if (s[pos] == ',') { |
130 | ++pos; |
131 | continue; |
132 | } |
133 | if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) == |
134 | std::numeric_limits<int32_t>::min()) |
135 | return false; |
136 | gen_col += qnt; |
137 | if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) == |
138 | std::numeric_limits<int32_t>::min()) |
139 | return false; |
140 | file_idx += qnt; |
141 | if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) == |
142 | std::numeric_limits<int32_t>::min()) |
143 | return false; |
144 | ori_line += qnt; |
145 | // Column number in source file is always 0 in source map generated by |
146 | // Emscripten. We just decode this value without further usage of it. |
147 | if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) == |
Although the value stored to 'qnt' is used in the enclosing expression, the value is never actually read from 'qnt' | |
148 | std::numeric_limits<int32_t>::min()) |
149 | return false; |
150 | |
151 | if (pos < s.size() && s[pos] != ',') return false; |
152 | pos++; |
153 | |
154 | file_idxs.push_back(file_idx); |
155 | source_row.push_back(ori_line); |
156 | offsets.push_back(gen_col); |
157 | } |
158 | return true; |
159 | } |
160 | |
161 | } // namespace wasm |
162 | } // namespace internal |
163 | } // namespace v8 |