Преглед изворни кода

Disabled alignment on AVR (fixes #1231)

Benoit Blanchon пре 5 година
родитељ
комит
67e78f0751

+ 1 - 0
CHANGELOG.md

@@ -8,6 +8,7 @@ HEAD
 * Fixed "statement is unreachable" warning on IAR (issue #1233)
 * Fixed "pointless integer comparison" warning on IAR (issue #1233)
 * Added CMake "install" target (issue #1209)
+* Disabled alignment on AVR (issue #1231)
 
 v6.15.0 (2020-03-22)
 -------

+ 5 - 3
extras/tests/MixedConfiguration/CMakeLists.txt

@@ -9,17 +9,19 @@ add_executable(MixedConfigurationTests
 	cpp11.cpp
 	decode_unicode_0.cpp
 	decode_unicode_1.cpp
+	enable_alignment_0.cpp
+	enable_alignment_1.cpp
+	enable_comments_0.cpp
+	enable_comments_1.cpp
 	enable_infinity_0.cpp
 	enable_infinity_1.cpp
 	enable_nan_0.cpp
 	enable_nan_1.cpp
+	enable_progmem_1.cpp
 	use_double_0.cpp
 	use_double_1.cpp
 	use_long_long_0.cpp
 	use_long_long_1.cpp
-	enable_progmem_1.cpp
-	enable_comments_1.cpp
-	enable_comments_0.cpp
 )
 
 target_link_libraries(MixedConfigurationTests

+ 41 - 0
extras/tests/MixedConfiguration/enable_alignment_0.cpp

@@ -0,0 +1,41 @@
+#define ARDUINOJSON_NAMESPACE ArduinoJson_NoAlignment
+#define ARDUINOJSON_ENABLE_ALIGNMENT 0
+#include <ArduinoJson.h>
+
+#include <catch.hpp>
+
+TEST_CASE("ARDUINOJSON_ENABLE_ALIGNMENT == 0") {
+  using namespace ARDUINOJSON_NAMESPACE;
+
+  const size_t N = sizeof(void*);
+
+  SECTION("isAligned()") {
+    CHECK(isAligned(0) == true);
+    CHECK(isAligned(1) == true);
+    CHECK(isAligned(N) == true);
+    CHECK(isAligned(N + 1) == true);
+    CHECK(isAligned(2 * N) == true);
+    CHECK(isAligned(2 * N + 1) == true);
+  }
+
+  SECTION("addPadding()") {
+    CHECK(addPadding(0) == 0);
+    CHECK(addPadding(1) == 1);
+    CHECK(addPadding(N) == N);
+    CHECK(addPadding(N + 1) == N + 1);
+  }
+
+  SECTION("AddPadding<>") {
+    const size_t a = AddPadding<0>::value;
+    CHECK(a == 0);
+
+    const size_t b = AddPadding<1>::value;
+    CHECK(b == 1);
+
+    const size_t c = AddPadding<N>::value;
+    CHECK(c == N);
+
+    const size_t d = AddPadding<N + 1>::value;
+    CHECK(d == N + 1);
+  }
+}

+ 40 - 0
extras/tests/MixedConfiguration/enable_alignment_1.cpp

@@ -0,0 +1,40 @@
+#define ARDUINOJSON_ENABLE_ALIGNMENT 1
+#include <ArduinoJson.h>
+
+#include <catch.hpp>
+
+TEST_CASE("ARDUINOJSON_ENABLE_ALIGNMENT == 1") {
+  using namespace ARDUINOJSON_NAMESPACE;
+
+  const size_t N = sizeof(void*);
+
+  SECTION("isAligned()") {
+    CHECK(isAligned(0) == true);
+    CHECK(isAligned(1) == false);
+    CHECK(isAligned(N) == true);
+    CHECK(isAligned(N + 1) == false);
+    CHECK(isAligned(2 * N) == true);
+    CHECK(isAligned(2 * N + 1) == false);
+  }
+
+  SECTION("addPadding()") {
+    CHECK(addPadding(0) == 0);
+    CHECK(addPadding(1) == N);
+    CHECK(addPadding(N) == N);
+    CHECK(addPadding(N + 1) == 2 * N);
+  }
+
+  SECTION("AddPadding<>") {
+    const size_t a = AddPadding<0>::value;
+    CHECK(a == 0);
+
+    const size_t b = AddPadding<1>::value;
+    CHECK(b == N);
+
+    const size_t c = AddPadding<N>::value;
+    CHECK(c == N);
+
+    const size_t d = AddPadding<N + 1>::value;
+    CHECK(d == 2 * N);
+  }
+}

+ 8 - 0
src/ArduinoJson/Configuration.hpp

@@ -203,6 +203,14 @@
 #endif
 #endif
 
+#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
+#if defined(__AVR)
+#define ARDUINOJSON_ENABLE_ALIGNMENT 0
+#else
+#define ARDUINOJSON_ENABLE_ALIGNMENT 1
+#endif
+#endif
+
 #ifndef ARDUINOJSON_TAB
 #define ARDUINOJSON_TAB "  "
 #endif

+ 32 - 8
src/ArduinoJson/Memory/Alignment.hpp

@@ -10,9 +10,11 @@
 
 namespace ARDUINOJSON_NAMESPACE {
 
-inline bool isAligned(void *ptr) {
+#if ARDUINOJSON_ENABLE_ALIGNMENT
+
+inline bool isAligned(size_t value) {
   const size_t mask = sizeof(void *) - 1;
-  size_t addr = reinterpret_cast<size_t>(ptr);
+  size_t addr = value;
   return (addr & mask) == 0;
 }
 
@@ -21,16 +23,38 @@ inline size_t addPadding(size_t bytes) {
   return (bytes + mask) & ~mask;
 }
 
-template <typename T>
-inline T *addPadding(T *p) {
-  size_t address = addPadding(reinterpret_cast<size_t>(p));
-  return reinterpret_cast<T *>(address);
-}
-
 template <size_t bytes>
 struct AddPadding {
   static const size_t mask = sizeof(void *) - 1;
   static const size_t value = (bytes + mask) & ~mask;
 };
 
+#else
+
+inline bool isAligned(size_t) {
+  return true;
+}
+
+inline size_t addPadding(size_t bytes) {
+  return bytes;
+}
+
+template <size_t bytes>
+struct AddPadding {
+  static const size_t value = bytes;
+};
+
+#endif
+
+template <typename T>
+inline bool isAligned(T *ptr) {
+  return isAligned(reinterpret_cast<size_t>(ptr));
+}
+
+template <typename T>
+inline T *addPadding(T *p) {
+  size_t address = addPadding(reinterpret_cast<size_t>(p));
+  return reinterpret_cast<T *>(address);
+}
+
 }  // namespace ARDUINOJSON_NAMESPACE

+ 4 - 0
src/ArduinoJson/Namespace.hpp

@@ -7,6 +7,8 @@
 #include <ArduinoJson/Configuration.hpp>
 #include <ArduinoJson/version.hpp>
 
+#ifndef ARDUINOJSON_NAMESPACE
+
 #define ARDUINOJSON_DO_CONCAT(A, B) A##B
 #define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_DO_CONCAT(A, B)
 #define ARDUINOJSON_CONCAT4(A, B, C, D) \
@@ -25,3 +27,5 @@
       ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_DECODE_UNICODE,                \
       ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY,               \
       ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_ENABLE_COMMENTS)
+
+#endif