@@ -44,6 +44,7 @@ using v8::Isolate; |
44 | 44 | using v8::Just; |
45 | 45 | using v8::JustVoid; |
46 | 46 | using v8::Local; |
| 47 | +using v8::LocalVector; |
47 | 48 | using v8::Maybe; |
48 | 49 | using v8::MaybeLocal; |
49 | 50 | using v8::Nothing; |
@@ -1155,16 +1156,17 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value, |
1155 | 1156 | if (!js_value->IsArray()) return Just<int>(UV_EINVAL); |
1156 | 1157 |
|
1157 | 1158 | Local<Context> context = env()->context(); |
1158 | | - js_array = js_value.As<Array>()->Clone().As<Array>(); |
| 1159 | + js_array = js_value.As<Array>(); |
1159 | 1160 | length = js_array->Length(); |
1160 | 1161 | data_size = 0; |
1161 | 1162 |
|
| 1163 | + LocalVector<String> values(isolate, length); |
| 1164 | + |
1162 | 1165 | // Index has a pointer to every string element, plus one more for a final |
1163 | 1166 | // null pointer. |
1164 | 1167 | list_size = (length + 1) * sizeof *list; |
1165 | 1168 |
|
1166 | | - // Convert all array elements to string. Modify the js object itself if |
1167 | | - // needed - it's okay since we cloned the original object. Also compute the |
| 1169 | + // Convert all array elements to string. Also compute the |
1168 | 1170 | // length of all strings, including room for a null terminator after every |
1169 | 1171 | // string. Align strings to cache lines. |
1170 | 1172 | for (uint32_t i = 0; i < length; i++) { |
@@ -1173,17 +1175,19 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value, |
1173 | 1175 | return Nothing<int>(); |
1174 | 1176 | } |
1175 | 1177 |
|
1176 | | - if (!value->IsString()) { |
| 1178 | + if (value->IsString()) { |
| 1179 | + values[i] = value.As<String>(); |
| 1180 | + } else { |
1177 | 1181 | Local<String> string; |
1178 | 1182 | if (!value->ToString(env()->isolate()->GetCurrentContext()) |
1179 | | - .ToLocal(&string) || |
1180 | | - js_array->Set(context, i, string).IsNothing()) { |
| 1183 | + .ToLocal(&string)) { |
1181 | 1184 | return Nothing<int>(); |
1182 | 1185 | } |
| 1186 | + values[i] = string; |
1183 | 1187 | } |
1184 | 1188 |
|
1185 | 1189 | size_t maybe_size; |
1186 | | - if (!StringBytes::StorageSize(isolate, value, UTF8).To(&maybe_size)) { |
| 1190 | + if (!StringBytes::StorageSize(isolate, values[i], UTF8).To(&maybe_size)) { |
1187 | 1191 | return Nothing<int>(); |
1188 | 1192 | } |
1189 | 1193 | data_size += maybe_size + 1; |
@@ -1197,15 +1201,8 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value, |
1197 | 1201 |
|
1198 | 1202 | for (uint32_t i = 0; i < length; i++) { |
1199 | 1203 | list[i] = buffer + data_offset; |
1200 | | - Local<Value> value; |
1201 | | - if (!js_array->Get(context, i).ToLocal(&value)) { |
1202 | | - return Nothing<int>(); |
1203 | | - } |
1204 | | - data_offset += StringBytes::Write(isolate, |
1205 | | - buffer + data_offset, |
1206 | | - -1, |
1207 | | - value, |
1208 | | - UTF8); |
| 1204 | + data_offset += |
| 1205 | + StringBytes::Write(isolate, buffer + data_offset, -1, values[i], UTF8); |
1209 | 1206 | buffer[data_offset++] = '\0'; |
1210 | 1207 | data_offset = nbytes::RoundUp(data_offset, sizeof(void*)); |
1211 | 1208 | } |
|