| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1fe4d30 commit 7e18f2e
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -477,10 +477,11 @@ void StringSlice<UCS2>(const FunctionCallbackInfo<Value>& args) { | |||
| 477 | 477 | // need to reorder on BE platforms. See http://nodejs.org/api/buffer.html | |
| 478 | 478 | // regarding Node's "ucs2" encoding specification. | |
| 479 | 479 | const bool aligned = (reinterpret_cast<uintptr_t>(data) % sizeof(*buf) == 0); | |
| 480 | - if (IsLittleEndian() && aligned) { | ||
| 481 | - buf = reinterpret_cast<const uint16_t*>(data); | ||
| 482 | - } else { | ||
| 480 | + if (IsLittleEndian() && !aligned) { | ||
| 483 | 481 | // Make a copy to avoid unaligned accesses in v8::String::NewFromTwoByte(). | |
| 482 | + // This applies ONLY to little endian platforms, as misalignment will be | ||
| 483 | + // handled by a byte-swapping operation in StringBytes::Encode on | ||
| 484 | + // big endian platforms. | ||
| 484 | 485 | uint16_t* copy = new uint16_t[length]; | |
| 485 | 486 | for (size_t i = 0, k = 0; i < length; i += 1, k += 2) { | |
| 486 | 487 | // Assumes that the input is little endian. | |
@@ -490,6 +491,8 @@ void StringSlice<UCS2>(const FunctionCallbackInfo<Value>& args) { | |||
| 490 | 491 | } | |
| 491 | 492 | buf = copy; | |
| 492 | 493 | release = true; | |
| 494 | + } else { | ||
| 495 | + buf = reinterpret_cast<const uint16_t*>(data); | ||
| 493 | 496 | } | |
| 494 | 497 | ||
| 495 | 498 | args.GetReturnValue().Set(StringBytes::Encode(env->isolate(), buf, length)); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | 7 | #include <limits.h> | |
| 8 | 8 | #include <string.h> // memcpy | |
| 9 | + #include <vector> | ||
| 9 | 10 | ||
| 10 | 11 | // When creating strings >= this length v8's gc spins up and consumes | |
| 11 | 12 | // most of the execution time. For these cases it's more performant to | |
@@ -406,9 +407,7 @@ size_t StringBytes::Write(Isolate* isolate, | |||
| 406 | 407 | reinterpret_cast<uintptr_t>(buf) % sizeof(uint16_t); | |
| 407 | 408 | if (is_aligned) { | |
| 408 | 409 | uint16_t* const dst = reinterpret_cast<uint16_t*>(buf); | |
| 409 | - for (size_t i = 0; i < nchars; i++) | ||
| 410 | - dst[i] = dst[i] << 8 | dst[i] >> 8; | ||
| 411 | - break; | ||
| 410 | + SwapBytes(dst, dst, nchars); | ||
| 412 | 411 | } | |
| 413 | 412 | ||
| 414 | 413 | ASSERT_EQ(sizeof(uint16_t), 2); | |
@@ -857,7 +856,16 @@ Local<Value> StringBytes::Encode(Isolate* isolate, | |||
| 857 | 856 | const uint16_t* buf, | |
| 858 | 857 | size_t buflen) { | |
| 859 | 858 | Local<String> val; | |
| 860 | - | ||
| 859 | + std::vector<uint16_t> dst; | ||
| 860 | + if (IsBigEndian()) { | ||
| 861 | + // Node's "ucs2" encoding expects LE character data inside a | ||
| 862 | + // Buffer, so we need to reorder on BE platforms. See | ||
| 863 | + // http://nodejs.org/api/buffer.html regarding Node's "ucs2" | ||
| 864 | + // encoding specification | ||
| 865 | + dst.resize(buflen); | ||
| 866 | + SwapBytes(&dst[0], buf, buflen); | ||
| 867 | + buf = &dst[0]; | ||
| 868 | + } | ||
| 861 | 869 | if (buflen < EXTERN_APEX) { | |
| 862 | 870 | val = String::NewFromTwoByte(isolate, | |
| 863 | 871 | buf, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -198,6 +198,20 @@ TypeName* Unwrap(v8::Local<v8::Object> object) { | |||
| 198 | 198 | return static_cast<TypeName*>(pointer); | |
| 199 | 199 | } | |
| 200 | 200 | ||
| 201 | + void SwapBytes(uint16_t* dst, const uint16_t* src, size_t buflen) { | ||
| 202 | + for (size_t i = 0; i < buflen; i++) { | ||
| 203 | + // __builtin_bswap16 generates more efficient code with | ||
| 204 | + // g++ 4.8 on PowerPC and other big-endian archs | ||
| 205 | + #ifdef __GNUC__ | ||
| 206 | + dst[i] = __builtin_bswap16(src[i]); | ||
| 207 | + #else | ||
| 208 | + dst[i] = (src[i] << 8) | (src[i] >> 8); | ||
| 209 | + #endif | ||
| 210 | + } | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + | ||
| 214 | + | ||
| 201 | 215 | } // namespace node | |
| 202 | 216 | ||
| 203 | 217 | #endif // SRC_UTIL_INL_H_ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -176,6 +176,8 @@ inline void ClearWrap(v8::Local<v8::Object> object); | |||
| 176 | 176 | template <typename TypeName> | |
| 177 | 177 | inline TypeName* Unwrap(v8::Local<v8::Object> object); | |
| 178 | 178 | ||
| 179 | + inline void SwapBytes(uint16_t* dst, const uint16_t* src, size_t buflen); | ||
| 180 | + | ||
| 179 | 181 | class Utf8Value { | |
| 180 | 182 | public: | |
| 181 | 183 | explicit Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> value); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments