16
16
17
17
#include " source-map.h"
18
18
#include " support/colors.h"
19
+ #include " support/json.h"
19
20
20
21
namespace wasm {
21
22
@@ -33,96 +34,55 @@ void MapParseException::dump(std::ostream& o) const {
33
34
Colors::normal (o);
34
35
}
35
36
36
- void SourceMapReader::readHeader (Module& wasm) {
37
- assert (pos == 0 );
37
+ void SourceMapReader::parse (Module& wasm) {
38
38
if (buffer.empty ()) {
39
39
return ;
40
40
}
41
-
42
- auto skipWhitespace = [&]() {
43
- while (pos < buffer.size () && (buffer[pos] == ' ' || buffer[pos] == ' \n ' )) {
44
- ++pos;
41
+ json::Value json;
42
+ json.parse (buffer.data (), json::Value::ASCII);
43
+ if (!json.isObject ()) {
44
+ throw MapParseException (" Source map is not valid JSON" );
45
+ }
46
+ if (!(json.has (" version" ) && json[" version" ]->isNumber () &&
47
+ json[" version" ]->getInteger () == 3 )) {
48
+ throw MapParseException (" Source map version missing or is not 3" );
49
+ }
50
+ if (!(json.has (" sources" ) && json[" sources" ]->isArray ())) {
51
+ throw MapParseException (" Source map sources missing or not an array" );
52
+ }
53
+ json::Ref s = json[" sources" ];
54
+ for (size_t i = 0 ; i < s->size (); i++) {
55
+ json::Ref v = s[i];
56
+ if (!(s[i]->isString ())) {
57
+ throw MapParseException (" Source map sources contains non-string" );
45
58
}
46
- };
47
-
48
- auto findField = [&](const char * name) {
49
- bool matching = false ;
50
- size_t len = strlen (name);
51
- size_t index = 0 ;
52
- while (1 ) {
53
- char ch = get ();
54
- if (ch == ' \" ' ) {
55
- if (matching) {
56
- if (index == len) {
57
- // We matched a terminating quote.
58
- break ;
59
- }
60
- matching = false ;
61
- } else {
62
- // Beginning of a new potential match.
63
- matching = true ;
64
- index = 0 ;
65
- }
66
- } else if (matching && name[index ] == ch) {
67
- ++index ;
68
- } else if (matching) {
69
- matching = false ;
70
- }
59
+ wasm.debugInfoFileNames .push_back (v->getCString ());
60
+ }
61
+
62
+ if (json.has (" names" )) {
63
+ json::Ref n = json[" names" ];
64
+ if (!n->isArray ()) {
65
+ throw MapParseException (" Source map names is not an array" );
71
66
}
72
- skipWhitespace ();
73
- expect (' :' );
74
- skipWhitespace ();
75
- return true ;
76
- };
77
-
78
- auto readString = [&](std::string& str) {
79
- std::vector<char > vec;
80
- skipWhitespace ();
81
- expect (' \" ' );
82
- while (1 ) {
83
- if (maybeGet (' \" ' )) {
84
- break ;
67
+ for (size_t i = 0 ; i < n->size (); i++) {
68
+ json::Ref v = n[i];
69
+ if (!v->isString ()) {
70
+ throw MapParseException (" Source map names contains non-string" );
85
71
}
86
- vec. push_back (get ());
72
+ wasm. debugInfoSymbolNames . push_back (v-> getCString ());
87
73
}
88
- skipWhitespace ();
89
- str = std::string (vec.begin (), vec.end ());
90
- };
91
-
92
- if (!findField (" sources" )) {
93
- throw MapParseException (" cannot find the 'sources' field in map" );
94
74
}
95
75
96
- skipWhitespace ();
97
- expect (' [' );
98
- if (!maybeGet (' ]' )) {
99
- do {
100
- std::string file;
101
- readString (file);
102
- wasm.debugInfoFileNames .push_back (file);
103
- } while (maybeGet (' ,' ));
104
- expect (' ]' );
76
+ if (!json.has (" mappings" )) {
77
+ throw MapParseException (" Source map mappings missing" );
105
78
}
106
-
107
- if (findField (" names" )) {
108
- skipWhitespace ();
109
- expect (' [' );
110
- if (!maybeGet (' ]' )) {
111
- do {
112
- std::string symbol;
113
- readString (symbol);
114
- wasm.debugInfoSymbolNames .push_back (symbol);
115
- } while (maybeGet (' ,' ));
116
- expect (' ]' );
117
- }
79
+ json::Ref m = json[" mappings" ];
80
+ if (!m->isString ()) {
81
+ throw MapParseException (" Source map mappings is not a string" );
118
82
}
119
83
120
- if (!findField (" mappings" )) {
121
- throw MapParseException (" cannot find the 'mappings' field in map" );
122
- }
123
-
124
- expect (' \" ' );
125
- if (maybeGet (' \" ' )) {
84
+ mappings = m->getCString ();
85
+ if (mappings.empty ()) {
126
86
// There are no mappings.
127
87
location = 0 ;
128
88
return ;
@@ -134,10 +94,6 @@ void SourceMapReader::readHeader(Module& wasm) {
134
94
135
95
std::optional<Function::DebugLocation>
136
96
SourceMapReader::readDebugLocationAt (size_t currLocation) {
137
- if (pos >= buffer.size ()) {
138
- return std::nullopt;
139
- }
140
-
141
97
while (location && location <= currLocation) {
142
98
do {
143
99
char next = peek ();
@@ -164,13 +120,13 @@ SourceMapReader::readDebugLocationAt(size_t currLocation) {
164
120
} while (false );
165
121
166
122
// Check whether there is another record to read the position for.
167
- char next = get ();
168
- if (next == ' \" ' ) {
123
+
124
+ if (peek () == ' \" ' ) {
169
125
// End of records.
170
126
location = 0 ;
171
127
break ;
172
128
}
173
- if (next != ' ,' ) {
129
+ if (get () != ' ,' ) {
174
130
throw MapParseException (" Expected delimiter" );
175
131
}
176
132
@@ -181,7 +137,6 @@ SourceMapReader::readDebugLocationAt(size_t currLocation) {
181
137
if (!hasInfo) {
182
138
return std::nullopt;
183
139
}
184
-
185
140
auto sym = hasSymbol ? symbol : std::optional<uint32_t >{};
186
141
return Function::DebugLocation{file, line, col, sym};
187
142
}
0 commit comments