|
32 | 32 | #include "tracing/trace_event.h" |
33 | 33 |
|
34 | 34 | #include "req_wrap-inl.h" |
| 35 | +#include "simdjson.h" |
35 | 36 | #include "stream_base-inl.h" |
36 | 37 | #include "string_bytes.h" |
| 38 | +#include "v8-primitive.h" |
37 | 39 |
|
38 | 40 | #include <fcntl.h> |
39 | 41 | #include <sys/types.h> |
@@ -1079,41 +1081,94 @@ static void InternalModuleReadJSON(const FunctionCallbackInfo<Value>& args) { |
1079 | 1081 | } |
1080 | 1082 |
|
1081 | 1083 | const size_t size = offset - start; |
1082 | | - char* p = &chars[start]; |
1083 | | - char* pe = &chars[size]; |
1084 | | - char* pos[2]; |
1085 | | - char** ppos = &pos[0]; |
1086 | | - |
1087 | | - while (p < pe) { |
1088 | | - char c = *p++; |
1089 | | - if (c == '\\' && p < pe && *p == '"') p++; |
1090 | | - if (c != '"') continue; |
1091 | | - *ppos++ = p; |
1092 | | - if (ppos < &pos[2]) continue; |
1093 | | - ppos = &pos[0]; |
1094 | | - |
1095 | | - char* s = &pos[0][0]; |
1096 | | - char* se = &pos[1][-1]; // Exclude quote. |
1097 | | - size_t n = se - s; |
1098 | | - |
1099 | | - if (n == 4) { |
1100 | | - if (0 == memcmp(s, "main", 4)) break; |
1101 | | - if (0 == memcmp(s, "name", 4)) break; |
1102 | | - if (0 == memcmp(s, "type", 4)) break; |
1103 | | - } else if (n == 7) { |
1104 | | - if (0 == memcmp(s, "exports", 7)) break; |
1105 | | - if (0 == memcmp(s, "imports", 7)) break; |
| 1084 | + simdjson::ondemand::parser parser; |
| 1085 | + simdjson::padded_string json_string(chars.data() + start, size); |
| 1086 | + simdjson::ondemand::document document; |
| 1087 | + simdjson::ondemand::object obj; |
| 1088 | + auto error = parser.iterate(json_string).get(document); |
| 1089 | + |
| 1090 | + if (error || document.get_object().get(obj)) { |
| 1091 | + args.GetReturnValue().Set(Array::New(isolate)); |
| 1092 | + return; |
| 1093 | + } |
| 1094 | + |
| 1095 | + auto js_string = [&](std::string_view sv) { |
| 1096 | + return ToV8Value(env->context(), sv, isolate).ToLocalChecked(); |
| 1097 | + }; |
| 1098 | + |
| 1099 | + bool includes_keys{false}; |
| 1100 | + Local<Value> name = Undefined(isolate); |
| 1101 | + Local<Value> main = Undefined(isolate); |
| 1102 | + Local<Value> exports = Undefined(isolate); |
| 1103 | + Local<Value> imports = Undefined(isolate); |
| 1104 | + Local<Value> type = Undefined(isolate); |
| 1105 | + bool parse_exports{false}; |
| 1106 | + bool parse_imports{false}; |
| 1107 | + |
| 1108 | + // Check for "name" field |
| 1109 | + std::string_view name_value{}; |
| 1110 | + if (!obj["name"].get_string().get(name_value)) { |
| 1111 | + name = js_string(name_value); |
| 1112 | + includes_keys = true; |
| 1113 | + } |
| 1114 | + |
| 1115 | + // Check for "main" field |
| 1116 | + std::string_view main_value{}; |
| 1117 | + if (!obj["main"].get_string().get(main_value)) { |
| 1118 | + main = js_string(main_value); |
| 1119 | + includes_keys = true; |
| 1120 | + } |
| 1121 | + |
| 1122 | + // Check for "exports" field |
| 1123 | + simdjson::ondemand::object exports_object; |
| 1124 | + std::string_view exports_value{}; |
| 1125 | + if (!obj["exports"].get_object().get(exports_object)) { |
| 1126 | + if (!exports_object.raw_json().get(exports_value)) { |
| 1127 | + exports = js_string(exports_value); |
| 1128 | + includes_keys = true; |
| 1129 | + parse_exports = true; |
| 1130 | + } |
| 1131 | + } else if (!obj["exports"].get(exports_value)) { |
| 1132 | + exports = js_string(exports_value); |
| 1133 | + includes_keys = true; |
| 1134 | + } |
| 1135 | + |
| 1136 | + // Check for "imports" field |
| 1137 | + simdjson::ondemand::object imports_object; |
| 1138 | + std::string_view imports_value; |
| 1139 | + if (!obj["imports"].get_object().get(imports_object)) { |
| 1140 | + if (!imports_object.raw_json().get(imports_value)) { |
| 1141 | + imports = js_string(imports_value); |
| 1142 | + includes_keys = true; |
| 1143 | + parse_imports = true; |
1106 | 1144 | } |
| 1145 | + } else if (!obj["imports"].get(imports_value)) { |
| 1146 | + imports = js_string(imports_value); |
| 1147 | + includes_keys = true; |
1107 | 1148 | } |
1108 | 1149 |
|
| 1150 | + // Check for "type" field |
| 1151 | + std::string_view type_value = "none"; |
| 1152 | + if (!obj["type"].get(type_value)) { |
| 1153 | + // Ignore unknown types for forwards compatibility |
| 1154 | + if (type_value != "module" && type_value != "commonjs") { |
| 1155 | + type_value = "none"; |
| 1156 | + } |
| 1157 | + includes_keys = true; |
| 1158 | + } |
| 1159 | + type = js_string(type_value); |
1109 | 1160 |
|
1110 | 1161 | Local<Value> return_value[] = { |
1111 | | - String::NewFromUtf8(isolate, |
1112 | | - &chars[start], |
1113 | | - v8::NewStringType::kNormal, |
1114 | | - size).ToLocalChecked(), |
1115 | | - Boolean::New(isolate, p < pe ? true : false) |
| 1162 | + Boolean::New(isolate, includes_keys), |
| 1163 | + name, |
| 1164 | + main, |
| 1165 | + exports, |
| 1166 | + imports, |
| 1167 | + type, |
| 1168 | + Boolean::New(isolate, parse_exports), |
| 1169 | + Boolean::New(isolate, parse_imports), |
1116 | 1170 | }; |
| 1171 | + |
1117 | 1172 | args.GetReturnValue().Set( |
1118 | 1173 | Array::New(isolate, return_value, arraysize(return_value))); |
1119 | 1174 | } |
|
0 commit comments