1616
1717#include " source-map.h"
1818#include " support/colors.h"
19+ #include " support/json.h"
1920
2021namespace wasm {
2122
@@ -33,96 +34,55 @@ void MapParseException::dump(std::ostream& o) const {
3334 Colors::normal (o);
3435}
3536
36- void SourceMapReader::readHeader (Module& wasm) {
37- assert (pos == 0 );
37+ void SourceMapReader::parse (Module& wasm) {
3838 if (buffer.empty ()) {
3939 return ;
4040 }
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" );
4558 }
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" );
7166 }
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" );
8571 }
86- vec. push_back (get ());
72+ wasm. debugInfoSymbolNames . push_back (v-> getCString ());
8773 }
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" );
9474 }
9575
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" );
10578 }
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" );
11882 }
11983
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 ()) {
12686 // There are no mappings.
12787 location = 0 ;
12888 return ;
@@ -134,10 +94,6 @@ void SourceMapReader::readHeader(Module& wasm) {
13494
13595std::optional<Function::DebugLocation>
13696SourceMapReader::readDebugLocationAt (size_t currLocation) {
137- if (pos >= buffer.size ()) {
138- return std::nullopt ;
139- }
140-
14197 while (location && location <= currLocation) {
14298 do {
14399 char next = peek ();
@@ -164,13 +120,13 @@ SourceMapReader::readDebugLocationAt(size_t currLocation) {
164120 } while (false );
165121
166122 // Check whether there is another record to read the position for.
167- char next = get ();
168- if (next == ' \" ' ) {
123+
124+ if (peek () == ' \" ' ) {
169125 // End of records.
170126 location = 0 ;
171127 break ;
172128 }
173- if (next != ' ,' ) {
129+ if (get () != ' ,' ) {
174130 throw MapParseException (" Expected delimiter" );
175131 }
176132
@@ -181,7 +137,6 @@ SourceMapReader::readDebugLocationAt(size_t currLocation) {
181137 if (!hasInfo) {
182138 return std::nullopt ;
183139 }
184-
185140 auto sym = hasSymbol ? symbol : std::optional<uint32_t >{};
186141 return Function::DebugLocation{file, line, col, sym};
187142}
0 commit comments