Pārlūkot izejas kodu

android: ChakraCore compiles to Android ARMv7

Oguz Bastemur 9 gadi atpakaļ
vecāks
revīzija
6811584cd0
63 mainītis faili ar 1695 papildinājumiem un 602 dzēšanām
  1. 1 0
      .gitignore
  2. 2 2
      Build/CMakeFeatureDetect.cmake
  3. 24 0
      Build/android_toolchain.sh
  4. 89 62
      CMakeLists.txt
  5. 5 1
      bin/CMakeLists.txt
  6. 10 8
      bin/ChakraCore/CMakeLists.txt
  7. 7 5
      bin/GCStress/CMakeLists.txt
  8. 19 10
      bin/ch/CMakeLists.txt
  9. 6 0
      bin/ch/stdafx.h
  10. 29 3
      build.sh
  11. 0 4
      lib/Backend/Backend.cpp
  12. 1 1
      lib/Common/Codex/CMakeLists.txt
  13. 7 2
      lib/Common/Common/ByteSwap.h
  14. 5 0
      lib/Common/Common/CMakeLists.txt
  15. 1 1
      lib/Common/Common/Int32Math.cpp
  16. 2 2
      lib/Common/Common/Int64Math.cpp
  17. 1 1
      lib/Common/Common/IntMathCommon.h
  18. 15 0
      lib/Common/Common/arm/arm_GET_CURRENT_FRAME.S
  19. 16 4
      lib/Common/CommonPal.h
  20. 6 0
      lib/Common/Core/CMakeLists.txt
  21. 1 1
      lib/Common/Core/SysInfo.cpp
  22. 12 22
      lib/Common/Memory/ArenaAllocator.cpp
  23. 5 0
      lib/Common/Memory/CMakeLists.txt
  24. 0 1
      lib/Common/Memory/MarkContext.inl
  25. 15 0
      lib/Common/Memory/arm/XDataAllocator.cpp
  26. 7 0
      lib/Common/Memory/arm/XDataAllocator.h
  27. 16 0
      lib/Common/Memory/arm/arm_SAVE_REGISTERS.S
  28. 6 0
      lib/Common/PlatformAgnostic/AssemblyCommon.h
  29. 6 0
      lib/Jsrt/CMakeLists.txt
  30. 5 4
      lib/Jsrt/JsrtHelper.cpp
  31. 5 6
      lib/Runtime/Language/Arguments.h
  32. 4 0
      lib/Runtime/Language/CMakeLists.txt
  33. 5 5
      lib/Runtime/Language/InterpreterStackFrame.cpp
  34. 4 2
      lib/Runtime/Library/CMakeLists.txt
  35. 4 4
      lib/Runtime/Library/DataView.cpp
  36. 2 0
      lib/Runtime/Library/JavascriptError.cpp
  37. 4 0
      lib/Runtime/Library/RuntimeLibraryPch.cpp
  38. 247 0
      lib/Runtime/Library/arm/arm_JavascriptFunctionA.S
  39. 2 2
      lib/Runtime/PlatformAgnostic/Platform/CMakeLists.txt
  40. 18 2
      pal/inc/pal.h
  41. 4 35
      pal/inc/pal_mstypes.h
  42. 0 23
      pal/inc/rt/safecrt.h
  43. 128 128
      pal/inc/strsafe.h
  44. 0 4
      pal/inc/unixasmmacros.inc
  45. 7 3
      pal/inc/unixasmmacrosamd64.inc
  46. 272 0
      pal/inc/unixasmmacrosarm.inc
  47. 39 22
      pal/src/CMakeLists.txt
  48. 65 0
      pal/src/arch/arm/asmconstants.h
  49. 30 0
      pal/src/arch/arm/asmhelpers.S
  50. 178 0
      pal/src/arch/arm/context2.S
  51. 17 0
      pal/src/arch/arm/debugbreak.S
  52. 34 0
      pal/src/arch/arm/exceptionhelper.S
  53. 45 0
      pal/src/arch/arm/processor.cpp
  54. 42 0
      pal/src/arch/i386/asmhelpers.S
  55. 129 1
      pal/src/configure.cmake
  56. 23 100
      pal/src/cruntime/file.cpp
  57. 35 90
      pal/src/cruntime/string.cpp
  58. 0 1
      pal/src/include/pal/file.h
  59. 0 2
      pal/src/include/pal/palinternal.h
  60. 1 1
      pal/src/loader/module.cpp
  61. 21 21
      pal/src/locale/unicode.cpp
  62. 10 7
      pal/src/misc/sysinfo.cpp
  63. 1 9
      pal/src/thread/pal_thread.cpp

+ 1 - 0
.gitignore

@@ -93,3 +93,4 @@ pal/src/config.h
 deps/
 
 .DS_Store
+android-toolchain-arm/

+ 2 - 2
Build/CMakeFeatureDetect.cmake

@@ -6,7 +6,7 @@
 include(CheckCXXSourceCompiles)
 include(CheckCXXSourceRuns)
 
-if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+if(CC_TARGET_OS_OSX)
     # by default this is disabled for osx
     # enable temporarily
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
@@ -33,7 +33,7 @@ else()
   set(CXX_DO_NOT_OPTIMIZE_SIBLING_CALLS "-fno-optimize-sibling-calls")
 endif()
 
-if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+if(CC_TARGET_OS_OSX)
     # by default this is disabled for osx
     # disable back
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \

+ 24 - 0
Build/android_toolchain.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------------------------------
+# Copyright (C) Microsoft. All rights reserved.
+# Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+#-------------------------------------------------------------------------------------------------------
+
+if [ $# -eq 0 ]
+then
+  echo "usage: android_toolchain <ndk_path>"
+  exit
+fi
+
+ANDROID_TARGET=android-21
+
+export TOOLCHAIN=$PWD/android-toolchain-arm
+rm -rf $TOOLCHAIN
+mkdir -p $TOOLCHAIN
+$1/build/tools/make-standalone-toolchain.sh \
+    --toolchain=arm-linux-androideabi-4.9 \
+    --arch=arm \
+    --install-dir=$TOOLCHAIN \
+    --platform=$ANDROID_TARGET --force
+
+rm $TOOLCHAIN/bin/python

+ 89 - 62
CMakeLists.txt

@@ -5,96 +5,112 @@ project (CHAKRACORE)
 # option. Otherwise, CMake fails to update cached
 # references
 if(SHARED_LIBRARY_SH)
-  unset(SHARED_LIBRARY_SH CACHE)
-  unset(STATIC_LIBRARY_SH CACHE)
-  unset(STATIC_LIBRARY CACHE)
-  set(SHARED_LIBRARY 1)
+    unset(SHARED_LIBRARY_SH CACHE)
+    unset(STATIC_LIBRARY_SH CACHE)
+    unset(STATIC_LIBRARY CACHE)
+    set(SHARED_LIBRARY 1)
 endif()
 
 if(STATIC_LIBRARY_SH)
-  unset(SHARED_LIBRARY_SH CACHE)
-  unset(STATIC_LIBRARY_SH CACHE)
-  unset(SHARED_LIBRARY CACHE)
-  set(STATIC_LIBRARY 1)
+    unset(SHARED_LIBRARY_SH CACHE)
+    unset(STATIC_LIBRARY_SH CACHE)
+    unset(SHARED_LIBRARY CACHE)
+    set(STATIC_LIBRARY 1)
 endif()
 
 if(CC_TARGETS_AMD64_SH)
-  unset(CC_TARGETS_X86 CACHE)
-  unset(CC_TARGETS_X86_SH CACHE)
-  unset(CC_TARGETS_AMD64_SH CACHE)
   set(CC_TARGETS_AMD64 1)
 endif()
 
 if(CC_TARGETS_X86_SH)
-  unset(CC_TARGETS_X86_SH CACHE)
-  unset(CC_TARGETS_AMD64_SH CACHE)
-  unset(CC_TARGETS_AMD64 CACHE)
-  set(CC_TARGETS_X86 1)
-  set(CMAKE_SYSTEM_PROCESSOR "i386")
+    set(CC_TARGETS_X86 1)
+    set(CMAKE_SYSTEM_PROCESSOR "i386")
 endif()
 
+if(CC_TARGETS_ARM_SH)
+    set(CC_TARGETS_ARM 1)
+    add_definitions(-D_ARM_=1)
+    set(CMAKE_SYSTEM_PROCESSOR "armv7l")
+endif()
+
+unset(CC_TARGETS_ARM_SH CACHE)
+unset(CC_TARGETS_X86_SH CACHE)
+unset(CC_TARGETS_AMD64_SH CACHE)
+
 if(ICU_SETTINGS_RESET)
-  unset(ICU_SETTINGS_RESET CACHE)
-  unset(ICU_INCLUDE_PATH CACHE)
-  unset(ICU_INCLUDE_PATH_SH CACHE)
-  unset(NO_ICU_PATH_GIVEN_SH CACHE)
-  unset(NO_ICU_PATH_GIVEN CACHE)
-  unset(CC_EMBED_ICU_SH CACHE)
+    unset(ICU_SETTINGS_RESET CACHE)
+    unset(ICU_INCLUDE_PATH CACHE)
+    unset(ICU_INCLUDE_PATH_SH CACHE)
+    unset(NO_ICU_PATH_GIVEN_SH CACHE)
+    unset(NO_ICU_PATH_GIVEN CACHE)
+    unset(CC_EMBED_ICU_SH CACHE)
+endif()
+
+if(CC_TARGET_OS_ANDROID_SH)
+    set(CC_TARGET_OS_ANDROID 1)
+    set(CMAKE_SYSTEM_NAME Android)
+    set(ANDROID_NDK "android-toolchain-arm/")
+    set(ANDROID_ABI armeabi-v7a)
+    set(CMAKE_SYSTEM_VERSION 21)
+    set(CMAKE_ANDROID_ARCH_ABI armeabi)
+    set(ANDROID_TOOLCHAIN_NAME arm-linux-androideabi-clang3.8)
+    set(ANDROID_STL "c++_static")
+    unset(CC_TARGET_OS_ANDROID_SH CACHE)
+elseif(CMAKE_SYSTEM_NAME STREQUAL Linux)
+    set(CC_TARGET_OS_LINUX 1)
+elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    set(CC_TARGET_OS_OSX 1)
 endif()
 
 if(CC_EMBED_ICU_SH)
-  unset(CC_EMBED_ICU_SH CACHE)
-  set(CC_EMBED_ICU 1)
-  set(ICU_INCLUDE_PATH "deps/icu/source/output/include/")
-  add_definitions(-DU_STATIC_IMPLEMENTATION)
+    unset(CC_EMBED_ICU_SH CACHE)
+    set(CC_EMBED_ICU 1)
+    set(ICU_INCLUDE_PATH "deps/icu/source/output/include/")
+    add_definitions(-DU_STATIC_IMPLEMENTATION)
 endif()
 
 if(ICU_INCLUDE_PATH_SH)
-  set(ICU_INCLUDE_PATH ${ICU_INCLUDE_PATH_SH})
-  unset(NO_ICU_PATH_GIVEN_SH CACHE)
-  unset(NO_ICU_PATH_GIVEN CACHE)
-  unset(ICU_INCLUDE_PATH_SH CACHE)
+    set(ICU_INCLUDE_PATH ${ICU_INCLUDE_PATH_SH})
+    unset(NO_ICU_PATH_GIVEN_SH CACHE)
+    unset(NO_ICU_PATH_GIVEN CACHE)
+    unset(ICU_INCLUDE_PATH_SH CACHE)
 endif()
 
 if(NO_ICU_PATH_GIVEN_SH)
-  set(NO_ICU_PATH_GIVEN ${NO_ICU_PATH_GIVEN_SH})
-  unset(NO_ICU_PATH_GIVEN_SH CACHE)
-  unset(ICU_INCLUDE_PATH_SH CACHE)
-  unset(ICU_INCLUDE_PATH CACHE)
+    set(NO_ICU_PATH_GIVEN ${NO_ICU_PATH_GIVEN_SH})
+    unset(NO_ICU_PATH_GIVEN_SH CACHE)
+    unset(ICU_INCLUDE_PATH_SH CACHE)
+    unset(ICU_INCLUDE_PATH CACHE)
 endif()
 
 function(clr_unknown_arch)
-  if (WIN32)
-      message(FATAL_ERROR "Only AMD64, ARM and I386 are supported")
-  else()
-      message(FATAL_ERROR "Only AMD64 and I386 are supported")
-  endif()
+    message(FATAL_ERROR "Only AMD64, ARM and I386 are supported")
 endfunction()
 
 if(ICU_INCLUDE_PATH)
-  add_definitions(-DHAS_REAL_ICU=1)
-  set(ICU_CC_PATH "${ICU_INCLUDE_PATH}/../lib/")
-  find_library(ICUUC icuuc PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-  find_library(ICU18 icui18n PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-  find_library(ICUDATA icudata PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-  if(ICUUC)
-    message("found libraries on ${ICU_CC_PATH}")
+    add_definitions(-DHAS_REAL_ICU=1)
+    set(ICU_CC_PATH "${ICU_INCLUDE_PATH}/../lib/")
+    find_library(ICUUC icuuc PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
+    find_library(ICU18 icui18n PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
+    find_library(ICUDATA icudata PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
+    if(ICUUC)
+      message("found libraries on ${ICU_CC_PATH}")
+      set(ICULIB
+        ${ICUUC}
+        ${ICU18}
+        ${ICUDATA}
+        )
+    endif()
+elseif(CC_EMBED_ICU)
+    set(ICU_CC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../deps/icu/source/output/lib/")
+    find_library(ICUUC icuuc PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
+    find_library(ICU18 icui18n PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
+    find_library(ICUDATA icudata PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
     set(ICULIB
       ${ICUUC}
       ${ICU18}
       ${ICUDATA}
       )
-  endif()
-elseif(CC_EMBED_ICU)
-  set(ICU_CC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../deps/icu/source/output/lib/")
-  find_library(ICUUC icuuc PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-  find_library(ICU18 icui18n PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-  find_library(ICUDATA icudata PATHS ${ICU_CC_PATH} NO_DEFAULT_PATH)
-  set(ICULIB
-    ${ICUUC}
-    ${ICU18}
-    ${ICUDATA}
-    )
 endif()
 
 set(CLR_CMAKE_PLATFORM_XPLAT 1)
@@ -110,11 +126,18 @@ elseif(CC_TARGETS_X86)
     set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} \
         -m32"
     )
+elseif(CC_TARGETS_ARM)
+    add_definitions(-D__arm__)
+    add_definitions(-D_M_IX86_OR_ARM32)
+    add_definitions(-D_M_ARM32_OR_ARM64)
+  if(CC_TARGET_OS_OSX)
+    add_compile_options(-arch arm)
+  endif()
 else()
     clr_unknown_arch()
 endif()
 
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+if(CC_TARGET_OS_LINUX OR CC_TARGET_OS_ANDROID)
     if(NOT ICULIB)
       if(NOT NO_ICU_PATH_GIVEN)
         if(NOT CC_EMBED_ICU)
@@ -127,10 +150,14 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux)
     set(CLR_CMAKE_PLATFORM_LINUX 1)
     # OSX 10.12 Clang deprecates libstdc++ [See GH #1599]
     # So, -Werror is linux only for now
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-        -Werror"
-        )
-elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    # + Android ARM ABI shows ld warnings
+    # xplat-todo: Do we need this ?
+    if (NOT CC_TARGET_OS_ANDROID)
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
+          -Werror"
+          )
+    endif()
+elseif(CC_TARGET_OS_OSX)
     add_definitions(
         -DPLATFORM_UNIX
     )

+ 5 - 1
bin/CMakeLists.txt

@@ -1,5 +1,9 @@
-add_subdirectory (GCStress)
+if(NOT CC_TARGET_OS_ANDROID)
+    add_subdirectory (GCStress)
+endif()
+
 add_subdirectory (ch)
+
 if(NOT STATIC_LIBRARY)
     add_subdirectory (ChakraCore)
 endif()

+ 10 - 8
bin/ChakraCore/CMakeLists.txt

@@ -21,7 +21,7 @@ target_include_directories (
 #  stdc++/gcc_s: C++ runtime code
 #  dl: For shared library loading related functions
 #
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
   set(LINKER_START_GROUP
     -Wl,--start-group
     -Wl,--whole-archive
@@ -32,7 +32,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux)
     -Wl,--end-group
     -static-libstdc++
     )
-elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+elseif(CC_TARGET_OS_OSX)
   set(LINKER_START_GROUP -Wl,-force_load,)
 endif()
 
@@ -49,14 +49,16 @@ set(lib_target "${lib_target}"
   ${ICULIB}
   )
 
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
   set(lib_target "${lib_target}"
     -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libChakraCoreLib.version
     )
-endif()
-
-if(CC_TARGETS_X86)
-  set(lib_target "${lib_target} -m32")
+elseif(CC_TARGET_OS_OSX)
+  if(CC_TARGETS_X86)
+    set(lib_target "${lib_target} -arch i386")
+  elseif(CC_TARGETS_ARM)
+    set(lib_target "${lib_target} -arch arm")
+  endif()
 endif()
 
 target_link_libraries (ChakraCore ${lib_target})
@@ -65,7 +67,7 @@ if(NOT CC_XCODE_PROJECT)
   set(CC_LIB_EXT "so")
   # Post build step to copy the built shared library
   # to BuildLinux (or whatever the CMakeBuildDir is)
-  if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+  if(CC_TARGET_OS_OSX)
     set(CC_LIB_EXT "dylib")
   endif()
 

+ 7 - 5
bin/GCStress/CMakeLists.txt

@@ -13,13 +13,15 @@ target_include_directories (GCStress
   $<BUILD_INTERFACE:${ROOT_SOURCE_DIR}/lib/Common/Memory>
   )
 
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
   set(LINKER_START_GROUP -Wl,--start-group)
   set(LINKER_END_GROUP -Wl,--end-group)
-endif()
-
-if(CC_TARGETS_X86)
-  set(lib_target "-m32")
+elseif(CC_TARGET_OS_OSX)
+  if(CC_TARGETS_X86)
+    set(lib_target "${lib_target} -arch i386")
+  elseif(CC_TARGETS_ARM)
+    set(lib_target "${lib_target} -arch arm")
+  endif()
 endif()
 
 # common link deps

+ 19 - 10
bin/ch/CMakeLists.txt

@@ -33,13 +33,20 @@ target_include_directories (ch
   )
 
 if(STATIC_LIBRARY)
-  if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+  if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
     set(LINKER_START_GROUP -Wl,--start-group)
     set(LINKER_END_GROUP -Wl,--end-group -static-libstdc++)
-  elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+  elseif(CC_TARGET_OS_OSX)
     set(LINKER_START_GROUP -Wl,-force_load,)
   endif()
 
+  if (NOT CC_TARGET_OS_ANDROID)
+    set(LINKER_END_GROUP
+        "${LINKER_END_GROUP}"
+        pthread
+        )
+  endif()
+
   # common link deps
   set(lib_target "${lib_target}"
     -Wl,-undefined,error
@@ -48,12 +55,11 @@ if(STATIC_LIBRARY)
     Chakra.Common.Core
     Chakra.Jsrt
     ${LINKER_END_GROUP}
-    pthread
     dl
     ${ICULIB}
     )
 
-  if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+  if(CC_TARGET_OS_OSX)
     set(lib_target "${lib_target}"
       "-framework CoreFoundation"
       "-framework Security"
@@ -62,7 +68,7 @@ if(STATIC_LIBRARY)
 else() # // shared library below
   set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE")
 
-  if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+  if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
       set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # osx clang sets this by default
   endif()
 
@@ -73,16 +79,19 @@ else() # // shared library below
     )
 endif()
 
-if(CC_TARGETS_X86)
-  set(lib_target "${lib_target} -arch i386")
-endif()
-
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
   set(lib_target "${lib_target}"
     -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/ch.version
     )
+elseif(CC_TARGET_OS_OSX)
+  if(CC_TARGETS_X86)
+    set(lib_target "${lib_target} -arch i386")
+  elseif(CC_TARGETS_ARM)
+    set(lib_target "${lib_target} -arch arm")
+  endif()
 endif()
 
+
 target_link_libraries (ch ${lib_target})
 
 if(NOT CC_XCODE_PROJECT)

+ 6 - 0
bin/ch/stdafx.h

@@ -258,3 +258,9 @@ inline JsErrorCode CreatePropertyIdFromString(const char* str, JsPropertyIdRef *
 {
     return ChakraRTInterface::JsCreatePropertyIdUtf8(str, strlen(str), Id);
 }
+
+#ifdef __ANDROID__
+#define S_IREAD   0000400
+#define S_IWRITE  0000200
+#define S_IEXEC   0000100
+#endif

+ 29 - 3
build.sh

@@ -46,6 +46,7 @@ PRINT_USAGE() {
     echo "      --sanitize=CHECKS Build with clang -fsanitize checks,"
     echo "                       e.g. undefined,signed-integer-overflow"
     echo "  -t, --test-build     Test build (by default Release build)"
+    echo "      --target[=S]     Target OS"
     echo "      --xcode          Generate XCode project"
     echo "      --without=FEATURE,FEATURE,..."
     echo "                       Disable FEATUREs from JSRT experimental"
@@ -78,6 +79,7 @@ OS_LINUX=0
 OS_APT_GET=0
 OS_UNIX=0
 LTO=""
+TARGET_OS=""
 
 if [ -f "/proc/version" ]; then
     OS_LINUX=1
@@ -231,6 +233,25 @@ while [[ $# -gt 0 ]]; do
         SANITIZE="-DCLANG_SANITIZE_SH=${SANITIZE}"
         ;;
 
+    --target=*)
+        _TARGET_OS=$1
+        _TARGET_OS="${_TARGET_OS:9}"
+        if [[ $_TARGET_OS =~ "android" ]]; then
+            OLD_PATH=$PATH
+            export TOOLCHAIN=$PWD/android-toolchain-arm
+            TARGET_OS="-DCC_TARGET_OS_ANDROID_SH=1 -DANDROID_TOOLCHAIN_DIR=${TOOLCHAIN}/arm-linux-androideabi"
+            export PATH=$TOOLCHAIN/bin:$OLD_PATH
+            export AR=arm-linux-androideabi-ar
+            export CC=arm-linux-androideabi-clang
+            export CXX=arm-linux-androideabi-clang++
+            export LINK=arm-linux-androideabi-clang++
+            export STRIP=arm-linux-androideabi-strip
+            # override CXX and CC
+            _CXX="${TOOLCHAIN}/bin/${CXX}"
+            _CC="${TOOLCHAIN}/bin/${CC}"
+        fi
+        ;;
+
     --without=*)
         FEATURES=$1
         FEATURES=${FEATURES:10}    # value after --without=
@@ -324,15 +345,20 @@ fi
 
 pushd $build_directory > /dev/null
 
-if [ $ARCH = "x86" ]; then
+if [[ $ARCH =~ "x86" ]]; then
     ARCH="-DCC_TARGETS_X86_SH=1"
     echo "Compile Target : x86"
 else
-    echo "Compile Target : amd64"
+    if [[ $ARCH =~ "arm" ]]; then
+        ARCH="-DCC_TARGETS_ARM_SH=1"
+        echo "Compile Target : arm"
+    else
+        echo "Compile Target : amd64"
+    fi
 fi
 
 echo Generating $BUILD_TYPE makefiles
-cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH $LTO $STATIC_LIBRARY $ARCH \
+cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH $LTO $STATIC_LIBRARY $ARCH $TARGET_OS \
     -DCMAKE_BUILD_TYPE=$BUILD_TYPE $SANITIZE $NO_JIT $WITHOUT_FEATURES ../..
 
 _RET=$?

+ 0 - 4
lib/Backend/Backend.cpp

@@ -3,7 +3,3 @@
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 #include "Backend.h"
-
-#if !ENABLE_OOP_NATIVE_CODEGEN
-JITManager JITManager::s_jitManager; // dummy object when OOP JIT disabled
-#endif

+ 1 - 1
lib/Common/Codex/CMakeLists.txt

@@ -7,6 +7,6 @@ if(NOT STATIC_LIBRARY)
 endif()
 add_library (Chakra.Common.Codex OBJECT
     Utf8Codex.cpp)
-  
+
 target_include_directories (
     Chakra.Common.Codex PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

+ 7 - 2
lib/Common/Common/ByteSwap.h

@@ -4,7 +4,7 @@
 //-------------------------------------------------------------------------------------------------------
 #pragma once
 
-#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175)) || defined(_M_ARM32_OR_ARM64)
+#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175)) || (defined(_M_ARM32_OR_ARM64) && defined(_MSC_FULL_VER))
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -50,12 +50,17 @@ RtlUlonglongByteSwap(
 #endif
 
 #elif defined(__APPLE__)
-#include <libkern/OSByteOrder.h> 
+#include <libkern/OSByteOrder.h>
 
 #define RtlUshortByteSwap(_x)    OSSwapInt16((_x))
 #define RtlUlongByteSwap(_x)     OSSwapInt32((_x))
 #define RtlUlonglongByteSwap(_x) OSSwapInt64((_x))
 
+#elif defined(__ANDROID__)
+#define RtlUshortByteSwap(_x)    __builtin_bswap16((_x))
+#define RtlUlongByteSwap(_x)     __builtin_bswap32((_x))
+#define RtlUlonglongByteSwap(_x) __builtin_bswap64((_x))
+
 #elif defined(__linux__)
 #include <byteswap.h>
 

+ 5 - 0
lib/Common/Common/CMakeLists.txt

@@ -1,3 +1,7 @@
+if(CC_TARGETS_ARM)
+    set(ARCH_SOURCES arm/arm_GET_CURRENT_FRAME.S)
+endif()
+
 add_library (Chakra.Common.Common OBJECT
     CfgLogger.cpp
     CommonCommonPch.cpp
@@ -13,6 +17,7 @@ add_library (Chakra.Common.Common OBJECT
     SmartFpuControl.cpp
     Tick.cpp
     vtinfo.cpp
+    ${ARCH_SOURCES}
 )
 
 target_include_directories (

+ 1 - 1
lib/Common/Common/Int32Math.cpp

@@ -22,7 +22,7 @@ Int32Math::Add(int32 left, int32 right, int32 *pResult)
 bool
 Int32Math::Mul(int32 left, int32 right, int32 *pResult)
 {
-#if __has_builtin(__builtin_mul_overflow)
+#if __has_builtin(__builtin_mul_overflow) && !(defined(_ARM_) && defined(__clang__))
     return IntMathCommon<int32>::Mul(left, right, pResult);
 #else
 

+ 2 - 2
lib/Common/Common/Int64Math.cpp

@@ -8,7 +8,7 @@
 #if defined(_M_X64)
 #if defined(_MSC_VER) && !defined(__clang__)
     #pragma intrinsic(_mul128)
-#elif !__has_builtin(__builtin_mul_overflow)
+#elif !(__has_builtin(__builtin_mul_overflow) && !(defined(_ARM_) && defined(__clang__))) // _ARM_ && __clang__ linker fails
     static int64 _mul128(const int64 left, const int64 right, int64 *high) noexcept
     {
         int64 low;
@@ -29,7 +29,7 @@
 bool
 Int64Math::Mul(int64 left, int64 right, int64 *pResult)
 {
-#if __has_builtin(__builtin_mul_overflow)
+#if __has_builtin(__builtin_mul_overflow) && !(defined(_ARM_) && defined(__clang__))
     return IntMathCommon<int64>::Mul(left, right, pResult);
 #else
 

+ 1 - 1
lib/Common/Common/IntMathCommon.h

@@ -82,7 +82,7 @@ bool IntMathCommon<T>::Sub(T left, T right, T *pResult)
 #endif
 }
 
-#if __has_builtin(__builtin_mul_overflow)
+#if __has_builtin(__builtin_mul_overflow) && !(defined(_ARM_) && defined(__clang__))
 template <class T>
 bool IntMathCommon<T>::Mul(T left, T right, T *pResult)
 {

+ 15 - 0
lib/Common/Common/arm/arm_GET_CURRENT_FRAME.S

@@ -0,0 +1,15 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+
+#include "unixasmmacros.inc"
+
+.syntax unified
+.thumb
+
+    // Var arm_GET_CURRENT_FRAME(void) //
+    LEAF_ENTRY arm_GET_CURRENT_FRAME, _TEXT
+        mov     r0,r11
+        bx      lr
+    LEAF_END arm_GET_CURRENT_FRAME, _TEXT

+ 16 - 4
lib/Common/CommonPal.h

@@ -94,8 +94,10 @@ __forceinline void  __int2c()
 #include <wchar.h>
 #include <math.h>
 #include <time.h>
+#if defined(_AMD64_) || defined(__i686__)
 #include <smmintrin.h>
 #include <xmmintrin.h>
+#endif // defined(_AMD64_) || defined(__i686__)
 #endif
 
 #include "inc/pal.h"
@@ -115,6 +117,7 @@ typedef GUID UUID;
 #define FILE PAL_FILE
 #endif
 
+#if defined(_AMD64_) || defined(__i686__)
 // xplat-todo: verify below is correct
 #include <cpuid.h>
 inline int get_cpuid(int cpuInfo[4], int function_id)
@@ -126,6 +129,14 @@ inline int get_cpuid(int cpuInfo[4], int function_id)
             reinterpret_cast<unsigned int*>(&cpuInfo[2]),
             reinterpret_cast<unsigned int*>(&cpuInfo[3]));
 }
+#elif defined(_ARM_)
+inline int get_cpuid(int cpuInfo[4], int function_id)
+{
+    int empty[4] = {0};
+    memcpy(cpuInfo, empty, sizeof(int) * 4);
+    // xplat-todo: implement me!!
+}
+#endif
 
 inline void DebugBreak()
 {
@@ -621,7 +632,7 @@ namespace PlatformAgnostic
 {
     __forceinline unsigned char _BitTestAndSet(LONG *_BitBase, int _BitPos)
     {
-#if defined(__clang__)
+#if defined(__clang__) && !defined(_ARM_)
         // Clang doesn't expand _bittestandset intrinic to bts, and it's implemention also doesn't work for _BitPos >= 32
         unsigned char retval = 0;
         asm(
@@ -637,9 +648,9 @@ namespace PlatformAgnostic
 #endif
     }
 
-    __forceinline unsigned char _BitTest(const LONG *_BitBase, int _BitPos)
+    __forceinline unsigned char _BitTest(LONG *_BitBase, int _BitPos)
     {
-#if defined(__clang__)
+#if defined(__clang__) && !defined(_ARM_)
         // Clang doesn't expand _bittest intrinic to bt, and it's implemention also doesn't work for _BitPos >= 32
         unsigned char retval;
         asm(
@@ -657,7 +668,7 @@ namespace PlatformAgnostic
 
     __forceinline unsigned char _InterlockedBitTestAndSet(volatile LONG *_BitBase, int _BitPos)
     {
-#if defined(__clang__)
+#if defined(__clang__) && !defined(_ARM_)
         // Clang doesn't expand _interlockedbittestandset intrinic to lock bts, and it's implemention also doesn't work for _BitPos >= 32
         unsigned char retval;
         asm(
@@ -678,3 +689,4 @@ namespace PlatformAgnostic
 #include "PlatformAgnostic/Numbers.h"
 #include "PlatformAgnostic/SystemInfo.h"
 #include "PlatformAgnostic/Thread.h"
+#include "PlatformAgnostic/AssemblyCommon.h"

+ 6 - 0
lib/Common/Core/CMakeLists.txt

@@ -22,3 +22,9 @@ add_library (Chakra.Common.Core STATIC
 
 target_include_directories (
     Chakra.Common.Core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+
+if(CC_TARGET_OS_ANDROID)
+    add_custom_command(TARGET Chakra.Common.Core POST_BUILD
+        COMMAND ${ANDROID_TOOLCHAIN_DIR}/bin/ranlib ${CMAKE_CURRENT_BINARY_DIR}/libChakra.Common.Core.a
+    )
+endif()

+ 1 - 1
lib/Common/Core/SysInfo.cpp

@@ -254,7 +254,7 @@ AutoSystemInfo::SSE2Available() const
     return false; // TODO: xplat support
 #endif
 #else
-    #error Unsupported platform.
+    return false;
 #endif
 }
 

+ 12 - 22
lib/Common/Memory/ArenaAllocator.cpp

@@ -459,7 +459,7 @@ ReleaseHeapMemory()
 
 template _ALWAYSINLINE char *ArenaAllocatorBase<InPlaceFreeListPolicy, 0, 0, 0>::AllocInternal(size_t requestedBytes);
 
-#if !(defined(__clang__) && defined(_M_IX86))
+#if !(defined(__clang__) && defined(_M_IX86_OR_ARM32))
 // otherwise duplicate instantination of AllocInternal Error
 template _ALWAYSINLINE char *ArenaAllocatorBase<InPlaceFreeListPolicy, 3, 0, 0>::AllocInternal(size_t requestedBytes);
 #endif
@@ -584,7 +584,7 @@ Free(void * buffer, size_t byteSize)
                 return;
             }
         }
- 
+
         void **policy = &this->freeList;
 #if DBG
         if (needsDelayFreeList)
@@ -821,10 +821,10 @@ void * InPlaceFreeListPolicy::Reset(void * policy)
 void InPlaceFreeListPolicy::MergeDelayFreeList(void * freeList)
 {
     if (!freeList) return;
-    
+
     FreeObject ** freeObjectLists = reinterpret_cast<FreeObject **>(freeList);
     FreeObject ** delayFreeObjectLists = freeObjectLists + buckets;
-    
+
     for (int i = 0; i < buckets; i++)
     {
         int size = (i + 1) << ArenaAllocator::ObjectAlignmentBitShift;
@@ -867,11 +867,6 @@ void InPlaceFreeListPolicy::VerifyFreeObjectIsFreeMemFilled(void * object, size_
 }
 #endif
 
-namespace Memory
-{
-    template class ArenaAllocatorBase<InPlaceFreeListPolicy>;
-}
-
 void * StandAloneFreeListPolicy::New(ArenaAllocatorBase<StandAloneFreeListPolicy> * /*allocator*/)
 {
     return NewInternal(InitialEntries);
@@ -1013,11 +1008,6 @@ bool StandAloneFreeListPolicy::TryEnsureFreeListEntry(StandAloneFreeListPolicy *
     return true;
 }
 
-namespace Memory
-{
-    template class ArenaAllocatorBase<StandAloneFreeListPolicy>;
-}
-
 #ifdef PERSISTENT_INLINE_CACHES
 
 void * InlineCacheFreeListPolicy::New(ArenaAllocatorBase<InlineCacheAllocatorTraits> * allocator)
@@ -1119,11 +1109,6 @@ void InlineCacheFreeListPolicy::Release(void * policy)
     }
 }
 
-namespace Memory
-{
-    template class ArenaAllocatorBase<InlineCacheAllocatorTraits>;
-}
-
 #if DBG
 bool InlineCacheAllocator::IsAllZero()
 {
@@ -1452,8 +1437,6 @@ void InlineCacheAllocator::ClearCachesWithDeadWeakRefs(Recycler* recycler)
 
 #else
 
-template class ArenaAllocatorBase<InlineCacheAllocatorTraits>;
-
 #if DBG
 bool InlineCacheAllocator::IsAllZero()
 {
@@ -1600,4 +1583,11 @@ void CacheAllocator::ZeroAll()
     }
 }
 
-#undef ASSERT_TRHEAD
+#undef ASSERT_THREAD
+
+namespace Memory
+{
+    template class ArenaAllocatorBase<InPlaceFreeListPolicy>;
+    template class ArenaAllocatorBase<StandAloneFreeListPolicy>;
+    template class ArenaAllocatorBase<InlineCacheAllocatorTraits>;
+}

+ 5 - 0
lib/Common/Memory/CMakeLists.txt

@@ -42,6 +42,11 @@ if(CC_TARGETS_AMD64)
         amd64/XDataAllocator.cpp
         amd64/amd64_SAVE_REGISTERS.S
     )
+elseif(CC_TARGETS_ARM)
+  set (CCM_SOURCE_FILES ${CCM_SOURCE_FILES}
+      arm/XDataAllocator.cpp
+      arm/arm_SAVE_REGISTERS.S
+  )
 endif()
 
 add_library (Chakra.Common.Memory OBJECT

+ 0 - 1
lib/Common/Memory/MarkContext.inl

@@ -210,4 +210,3 @@ void MarkContext::ProcessMark()
 
     Assert(markStack.IsEmpty());
 }
-

+ 15 - 0
lib/Common/Memory/arm/XDataAllocator.cpp

@@ -11,6 +11,10 @@ CompileAssert(false)
 #include "XDataAllocator.h"
 #include "Core/DelayLoadLibrary.h"
 
+#ifndef _WIN32
+#include "PlatformAgnostic/AssemblyCommon.h" // __REGISTER_FRAME / __DEREGISTER_FRAME
+#endif
+
 XDataAllocator::XDataAllocator(BYTE* address, uint size)
 {
     Assert(size == 0);
@@ -60,6 +64,7 @@ void XDataAllocator::Release(const SecondaryAllocation& allocation)
 /* static */
 void XDataAllocator::Register(XDataAllocation * xdataInfo, DWORD functionStart, DWORD functionSize)
 {
+#ifdef _WIN32
     RUNTIME_FUNCTION* pdataArray = xdataInfo->GetPdataArray();
     for (ushort i = 0; i < xdataInfo->pdataCount; i++)
     {
@@ -84,12 +89,22 @@ void XDataAllocator::Register(XDataAllocation * xdataInfo, DWORD functionStart,
         /*RangeEnd*/ functionStart + functionSize);
 
     Js::Throw::CheckAndThrowOutOfMemory(NT_SUCCESS(status));
+
+#else  // !_WIN32
+    Assert(ReadHead(xdataInfo->address));  // should be non-empty .eh_frame
+    __REGISTER_FRAME(xdataInfo->address);
+#endif
 }
 
 /* static */
 void XDataAllocator::Unregister(XDataAllocation * xdataInfo)
 {
+#ifdef _WIN32
     NtdllLibrary::Instance->DeleteGrowableFunctionTable(xdataInfo->functionTable);
+#else  // !_WIN32
+    Assert(ReadHead(xdataInfo->address));  // should be non-empty .eh_frame
+    __DEREGISTER_FRAME(xdataInfo->address);
+#endif
 }
 
 bool XDataAllocator::CanAllocate()

+ 7 - 0
lib/Common/Memory/arm/XDataAllocator.h

@@ -61,4 +61,11 @@ public:
 
     static void Register(XDataAllocation * xdataInfo, DWORD functionStart, DWORD functionSize);
     static void Unregister(XDataAllocation * xdataInfo);
+#ifndef _WIN32
+    // Read .eh_frame data head (length record). 0 means empty.
+    static uint32 ReadHead(const void* p)
+    {
+        return *reinterpret_cast<const uint32*>(p);
+    }
+#endif
 };

+ 16 - 0
lib/Common/Memory/arm/arm_SAVE_REGISTERS.S

@@ -0,0 +1,16 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+
+#include "unixasmmacros.inc"
+
+.syntax unified
+.thumb
+
+    LEAF_ENTRY arm_SAVE_REGISTERS, _TEXT
+        str     sp, [r0], #+4
+        stmia   r0, {r1-r12}
+
+        bx      lr
+    LEAF_END arm_SAVE_REGISTERS, _TEXT

+ 6 - 0
lib/Common/PlatformAgnostic/AssemblyCommon.h

@@ -29,4 +29,10 @@ void mac_fde_wrapper(const char *dataStart, mac_fde_reg_op reg_op);
 #define __DEREGISTER_FRAME(addr)
 #endif // _AMD64_ && !DISABLE_JIT
 
+#ifdef _M_ARM
+#define __iso_volatile_load32(x) (*(const volatile __int32*)x)
+#elif defined(_M_ARM64)
+#define __iso_volatile_load64(x) (*(const volatile __int64*)x)
+#endif
+
 #endif // !_WIN32

+ 6 - 0
lib/Jsrt/CMakeLists.txt

@@ -52,3 +52,9 @@ target_include_directories (
     ../Runtime/Debug
     ../Parser
     )
+
+if(CC_TARGET_OS_ANDROID)
+    add_custom_command(TARGET Chakra.Jsrt POST_BUILD
+        COMMAND ${ANDROID_TOOLCHAIN_DIR}/bin/ranlib ${CMAKE_CURRENT_BINARY_DIR}/libChakra.Jsrt.a
+    )
+endif()

+ 5 - 4
lib/Jsrt/JsrtHelper.cpp

@@ -2,6 +2,11 @@
 // Copyright (C) Microsoft. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
+
+#if !defined(_WIN32)
+#include <pthread.h>
+#endif
+
 #include "JsrtPch.h"
 #include "jsrtHelper.h"
 #include "Base/ThreadContextTlsEntry.h"
@@ -14,10 +19,6 @@
 #include "Core/ConfigParser.h"
 #include "Base/ThreadBoundThreadContextManager.h"
 
-#ifndef _WIN32
-#include <pthread.h>
-#endif
-
 #ifdef CHAKRA_STATIC_LIBRARY
 bool ConfigParserAPI::FillConsoleTitle(__ecount(cchBufferSize) LPWSTR buffer, size_t cchBufferSize, __in LPWSTR moduleName)
 {

+ 5 - 6
lib/Runtime/Language/Arguments.h

@@ -13,9 +13,8 @@
     va_start(_vl, callInfo);                                        \
     Js::Var* va = (Js::Var*)_vl
 #else
-#if defined(_M_X64) || defined(_M_IX86)
 // We use a custom calling convention to invoke JavascriptMethod based on
-// System V AMD64 ABI. At entry of JavascriptMethod the stack layout is:
+// System ABI. At entry of JavascriptMethod the stack layout is:
 //      [Return Address] [function] [callInfo] [arg0] [arg1] ...
 //
 #define DECLARE_ARGS_VARARRAY_N(va, n)                              \
@@ -58,10 +57,6 @@ inline int _count_args(const T1&, const T2&, const T3&, const T4&, Js::CallInfo
 {
     return 5;
 }
-
-#else
-#error Not yet implemented
-#endif
 #endif
 
 
@@ -75,6 +70,10 @@ inline int _count_args(const T1&, const T2&, const T3&, const T4&, Js::CallInfo
 #define CALL_ENTRYPOINT(entryPoint, function, callInfo, ...) \
     entryPoint(function, callInfo, nullptr, nullptr, nullptr, nullptr, \
                function, callInfo, ##__VA_ARGS__)
+#elif defined(_ARM_)
+// xplat-todo: fix me ARM
+#define CALL_ENTRYPOINT(entryPoint, function, callInfo, ...) \
+    entryPoint(function, callInfo, ##__VA_ARGS__)
 #else
 #error CALL_ENTRYPOINT not yet implemented
 #endif

+ 4 - 0
lib/Runtime/Language/CMakeLists.txt

@@ -77,6 +77,10 @@ elseif(CC_TARGETS_X86)
         i386/AsmJsJitTemplate.cpp
         i386/StackFrame.cpp
     )
+elseif(CC_TARGETS_ARM)
+    set (CRL_SOURCE_FILES ${CRL_SOURCE_FILES}
+        arm/StackFrame.cpp
+    )
 endif()
 
 add_library (Chakra.Runtime.Language OBJECT ${CRL_SOURCE_FILES})

+ 5 - 5
lib/Runtime/Language/InterpreterStackFrame.cpp

@@ -1576,7 +1576,7 @@ namespace Js
                 IsFloat = 1 << AsmJsRetType::Float,
                 IsDouble = 1 << AsmJsRetType::Double,
                 IsInt64 = 1 << AsmJsRetType::Int64,
-                IsSimd = 
+                IsSimd =
                     1 << AsmJsRetType::Int32x4 |
                     1 << AsmJsRetType::Bool32x4 |
                     1 << AsmJsRetType::Bool16x8 |
@@ -2214,7 +2214,7 @@ namespace Js
         return entryPoint;
     }
 
-    
+
 
 
     template<typename T>
@@ -2491,7 +2491,7 @@ namespace Js
 
     void InterpreterStackFrame::TraceAsmJsOpCode(InterpreterStackFrame* that, Js::OpCodeAsmJs op)
     {
-#if DBG_DUMP && defined(ASMJS_PLAT) 
+#if DBG_DUMP && defined(ASMJS_PLAT)
         if(PHASE_TRACE(Js::AsmjsInterpreterPhase, that->m_functionBody))
         {
             Output::Print(_u("%d.%d:Executing %s at offset 0x%X\n"), that->m_functionBody->GetSourceContextId(), that->m_functionBody->GetLocalFunctionId(), Js::OpCodeUtilAsmJs::GetOpCodeName(op), that->DEBUG_currentByteOffset);
@@ -8839,7 +8839,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
     void InterpreterStackFrame::TrySetFrameObjectInHeapArgObj(ScriptContext * scriptContext, bool hasNonSimpleParams, bool isScopeObjRestored)
     {
         ActivationObject * frameObject = nullptr;
-        
+
         uint32 formalsCount = this->m_functionBody->GetInParamsCount() - 1;
         Js::PropertyIdArray * propIds = nullptr;
         Js::HeapArgumentsObject* heapArgObj = nullptr;
@@ -8851,7 +8851,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
         }
 
         bool isCachedScope = false;
-        
+
         //For Non-simple params, we don't have a scope object created.
         if (this->m_functionBody->NeedScopeObjectForArguments(hasNonSimpleParams))
         {

+ 4 - 2
lib/Runtime/Library/CMakeLists.txt

@@ -120,8 +120,10 @@ if(CC_TARGETS_AMD64)
     set (CRLIB_SOURCE_CODES ${CRLIB_SOURCE_CODES}
         amd64/JavascriptFunctionA.S
     )
-elseif(CC_TARGETS_X86)
-    # x86 here
+elseif(CC_TARGETS_ARM)
+    set (CRLIB_SOURCE_CODES ${CRLIB_SOURCE_CODES}
+        arm/arm_JavascriptFunctionA.S
+    )
 endif()
 
 add_library (Chakra.Runtime.Library OBJECT ${CRLIB_SOURCE_CODES})

+ 4 - 4
lib/Runtime/Library/DataView.cpp

@@ -684,25 +684,25 @@ namespace Js
 #ifdef _M_ARM
     // Provide template specialization (only) for memory access at unaligned float/double address which causes data alignment exception otherwise.
     template<>
-    Var DataView::GetValueWithCheck<float>(uint32 byteOffset, const char16 *funcName, BOOL isLittleEndian = FALSE)
+    Var DataView::GetValueWithCheck<float>(uint32 byteOffset, const char16 *funcName, BOOL isLittleEndian)
     {
         return this->GetValueWithCheck<float, float UNALIGNED*>(byteOffset, isLittleEndian, funcName);
     }
 
     template<>
-    Var DataView::GetValueWithCheck<double>(uint32 byteOffset, const char16 *funcName, BOOL isLittleEndian = FALSE)
+    Var DataView::GetValueWithCheck<double>(uint32 byteOffset, const char16 *funcName, BOOL isLittleEndian)
     {
         return this->GetValueWithCheck<double, double UNALIGNED*>(byteOffset, isLittleEndian, funcName);
     }
 
     template<>
-    void DataView::SetValue<float>(uint32 byteOffset, float value, const char16 *funcName, BOOL isLittleEndian = FALSE)
+    void DataView::SetValue<float>(uint32 byteOffset, float value, const char16 *funcName, BOOL isLittleEndian)
     {
         this->SetValue<float, float UNALIGNED*>(byteOffset, value, isLittleEndian, funcName);
     }
 
     template<>
-    void DataView::SetValue<double>(uint32 byteOffset, double value, const char16 *funcName, BOOL isLittleEndian = FALSE)
+    void DataView::SetValue<double>(uint32 byteOffset, double value, const char16 *funcName, BOOL isLittleEndian)
     {
         this->SetValue<double, double UNALIGNED*>(byteOffset, value, isLittleEndian, funcName);
     }

+ 2 - 0
lib/Runtime/Library/JavascriptError.cpp

@@ -371,7 +371,9 @@ namespace Js
 
         if (FACILITY_CONTROL == HRESULT_FACILITY(hr) || FACILITY_JSCRIPT == HRESULT_FACILITY(hr))
         {
+#if !(defined(_M_ARM) && defined(__clang__))
             if (argList != nullptr)
+#endif
             {
                 HRESULT hrAdjusted = GetAdjustedResourceStringHr(hr, /* isFormatString */ true);
 

+ 4 - 0
lib/Runtime/Library/RuntimeLibraryPch.cpp

@@ -3,3 +3,7 @@
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 #include "RuntimeLibraryPch.h"
+
+#if !ENABLE_OOP_NATIVE_CODEGEN
+JITManager JITManager::s_jitManager; // dummy object when OOP JIT disabled
+#endif

+ 247 - 0
lib/Runtime/Library/arm/arm_JavascriptFunctionA.S

@@ -0,0 +1,247 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+
+#include "unixasmmacros.inc"
+
+.syntax unified
+.thumb
+
+// .thumb
+.global C_FUNC(_ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz)
+.global C_FUNC(_ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz)
+// .arm
+.global C_FUNC(arm_CallFunction)
+.global C_FUNC(arm_CallEhFrame)
+.global C_FUNC(arm_CallCatch)
+
+    NESTED_ENTRY _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT, NoHandler
+        push_nonvol_reg {r0-r3}
+        push_nonvol_reg {r11}
+        push_nonvol_reg {lr}
+
+        bl      _ZN2Js18JavascriptFunction19DeferredDeserializeEPNS_14ScriptFunctionE
+        mov     r12,r0              // back up entryPoint in R12
+
+        pop_nonvol_reg {lr}
+        pop_nonvol_reg {r11}
+        pop_nonvol_reg {r0-r3}
+        bx      r12          // jump (tail call) to new entryPoint
+    NESTED_END _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT
+
+
+    NESTED_ENTRY _ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT, NoHandler
+        push_nonvol_reg {r0-r3}
+        push_nonvol_reg {r11}
+        push_nonvol_reg {lr}
+
+
+        mov     r0, sp              // Pass the address of the function at the saved r0 in case it need to be boxed
+        bl      _ZN2Js18JavascriptFunction13DeferredParseEPPNS_14ScriptFunctionE
+        mov     r12,r0              // back up entryPoint in R12
+
+        pop_nonvol_reg {lr}
+        pop_nonvol_reg {r11}
+        pop_nonvol_reg {r0-r3}
+        bx      r12          // jump (tail call) to new entryPoint
+    NESTED_END _ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT
+
+.arm
+    NESTED_ENTRY arm_CallFunction, _TEXT, NoHandler
+
+    // IMPORTANT: the number of pushed registers (even vs odd) must be consistent with 8-bytes align check below.
+    PROLOG_PUSH {r4-r7}   // r6 is saved for stack alignment, this does: add r11,sp,#10 as well
+    PROLOG_PUSH {r11}
+    PROLOG_PUSH {lr}
+#if defined(_CONTROL_FLOW_GUARD)
+    PROLOG_PUSH {r8-r9}          // extra register to save info across icall check, and one register to maintain alignment
+#endif
+    PROLOG_STACK_SAVE r7       // mov r7,sp -- save stack frame for restoring at the epilog.
+
+
+    // All but two values go onto the stack ... calculate the number of values on the stack.
+    mov     r4,r1               // r4 = callInfo.
+    bfc     r4,#24,#8           // clear high order 8 bits of r6 -- clean callInfo.Flags which shares same word as callInfo.Count.
+    sub     r4,r4,#2            // subtract 2 == number of values that we can pass via registers.
+    mov     r5,r4,lsl #2        // r5 = space needed on the stack for values.
+
+    // Adjust sp to meet ABI requirement: stack must be 8-bytes aligned at any function boundary.
+    // Each reg is 4 bytes, so as we push 4 (even) regs above, r1 == odd number of regs breaks 8-byte alignment, even is OK.
+    asrs    r12,r4,#1           // r-shift r1 into carry - set carry flag if r4 is odd. Note: the value in r12 is not used.
+    addcs   r4, r4, #1            // if carry is set, add space for one more argument on stack to guarantee 8-byte alignment.
+
+    // offset stack by the amount of space we'll need.
+    sub     sp,sp,r4
+
+    mov     r4,r3                               // copy entryPoint to r4 so we can use r3 as a scratch variable
+
+    add     r2,r2,#8                            // add 8 to r2 (so it is the address of the first value to be placed on the stack).
+    mov     r12,#0                              // offset for getting values/storing on stack.
+
+LOCAL_LABEL(argN):
+    cmp     r5,r12
+    beq     LOCAL_LABEL(arg2)                   // if r5 == r12, no more values need to go onto the stack.
+
+        ldr     r3,[r2,r12]                     // r3 = *(r2 + r12)
+        str     r3,[sp,r12]                     // *(sp + r12) = r3
+
+        add     r12,r12,#4                      // offset increases by 4.
+    b   LOCAL_LABEL(argN)                       // goto argN
+
+LOCAL_LABEL(arg2):
+    // Verify that the call target is valid, and process last two arguments
+#if defined(_CONTROL_FLOW_GUARD)
+    mov     r5, r0    // save argument registers
+    mov     r6, r1
+    mov     r8, r2
+
+    mov     r0, r4    // the target address to check
+    mov32   r12, __guard_check_icall_fptr
+    ldr     r12, [r12]
+    blx     r12
+
+    mov     r0, r5    // restore argument registers
+    mov     r1, r6
+    mov     r2, r8
+#endif
+
+    // Push values[1] into r3
+    ldr     r3,[r2,#-4]                         // r3 = *(r2-4) = values[1]
+
+    // Push values[0] into r2
+    ldr     r2,[r2,#-8]                         // r2 = *(r2-8) = values[0]
+
+    blx     r4                                  // call r4 (== entry point)
+
+    EPILOG_STACK_RESTORE r7
+#if defined(_CONTROL_FLOW_GUARD)
+    EPILOG_POP {r8-r9}
+#endif
+    EPILOG_POP {pc}
+    EPILOG_POP {r11}
+    EPILOG_POP {r4-r7}
+
+    NESTED_END arm_CallFunction, _TEXT
+
+
+    NESTED_ENTRY arm_CallEhFrame, _TEXT, NoHandler
+
+    // Params:
+    // r0 -- thunk target
+    // r1 -- frame pointer
+    // r2 -- locals pointer
+    // r3 -- size of stack args area
+
+    // Home params and save registers
+    // Push r11 to create the equivalent of the stack nested function list (doesn't matter what is stored there)
+    // Push r12 to create the equivalent of the arguments object slot (doesn't matter what is stored there)
+    PROLOG_PUSH {r0-r3}
+    PROLOG_PUSH {r11}
+    PROLOG_PUSH {lr}
+    PROLOG_PUSH {r4-r12}
+    PROLOG_VPUSH {d8-d15}
+    // Save a pointer to the saved registers
+    PROLOG_STACK_SAVE r4
+    PROLOG_PUSH {r4}
+
+    // Set up the frame pointer and locals pointer
+    mov r7,r2
+    mov r11,r1
+
+    // Allocate the arg out area, calling chkstk if necessary
+    cmp r3,4096
+    bge LOCAL_LABEL(chkstk_call)
+    sub sp,r3
+
+    // Verify that the call target is valid
+#if 0 && defined(_CONTROL_FLOW_GUARD)
+    // we have used the r1-r3 info to set up the fake frame
+    // they aren't needed by the jitted code that we're going to thunk to
+    // so we don't preserve them across the __guard_check_icall_fptr call
+    mov     r5, r0
+
+    mov32   r12, __guard_check_icall_fptr
+    ldr     r12, [r12]
+    blx     r12
+
+    mov     r0, r5
+#endif
+
+    // Thunk to the jitted code (and don't return)
+    bx  r0
+
+LOCAL_LABEL(chkstk_call):
+    // Call chkstk, passing a DWORD count in r4
+    lsr r4,r3,#2
+    // bl |__chkstk|
+    // r4 is now the byte count to be allocated
+    sub sp,r4
+
+    // Thunk to the jitted code (and don't return)
+    bx  r0
+
+    NESTED_END arm_CallEhFrame, _TEXT
+
+
+    NESTED_ENTRY arm_CallCatch, _TEXT, NoHandler
+
+    // Params:
+    // r0 -- thunk target
+    // r1 -- frame pointer
+    // r2 -- locals pointer
+    // r3 -- size of stack args area
+    // [sp] -- exception object
+
+    // Home params and save registers
+    // Push r11 to create the equivalent of the stack nested function list (doesn't matter what is stored there)
+    // Push r12 to create the equivalent of the arguments object slot (doesn't matter what is stored there)
+    PROLOG_PUSH {r0-r3}
+    PROLOG_PUSH {r11}
+    PROLOG_PUSH {lr}
+    PROLOG_PUSH {r4-r12}
+    PROLOG_VPUSH {d8-d15}
+    // Save a pointer to the saved registers
+    PROLOG_STACK_SAVE r4
+    PROLOG_PUSH {r4}
+
+    // Set up the frame pointer and locals pointer
+    mov r7,r2
+    mov r11,r1
+
+    // Load the exception object from [sp, 16 (homed params) + 44 (saved registers) + 64 (double registers) + 4 (saved SP) == 128]
+    ldr r1,[sp,#128]
+
+    // Allocate the arg out area, calling chkstk if necessary
+    cmp r3,4096
+    bge LOCAL_LABEL(chkstk_call_catch)
+    sub sp,r3
+
+    // Verify that the call target is valid
+#if 0 && defined(_CONTROL_FLOW_GUARD)
+    // we have used the r1-r3 info to set up the fake frame
+    // they aren't needed by the jitted code that we're going to thunk to
+    // so we don't preserve them across the __guard_check_icall_fptr call
+    mov     r5, r0
+
+    mov32   r12, __guard_check_icall_fptr
+    ldr     r12, [r12]
+    blx     r12
+
+    mov     r0, r5
+#endif
+
+    // Thunk to the jitted code (and don't return)
+    bx  r0
+
+LOCAL_LABEL(chkstk_call_catch):
+    // Call chkstk, passing a DWORD count in r4
+    lsr r4,r3,#2
+    // bl |__chkstk|
+    // r4 is now the byte count to be allocated
+    sub sp,r4
+
+    // Thunk to the jitted code (and don't return)
+    bx r0
+
+    NESTED_END arm_CallCatch, _TEXT

+ 2 - 2
lib/Runtime/PlatformAgnostic/Platform/CMakeLists.txt

@@ -8,12 +8,12 @@ set(PL_SOURCE_FILES
   Linux/Thread.cpp
   )
 
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
 set(PL_SOURCE_FILES ${PL_SOURCE_FILES}
   Linux/DateTime.cpp
   Linux/SystemInfo.cpp
   )
-elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+elseif(CC_TARGET_OS_OSX)
 set(PL_SOURCE_FILES ${PL_SOURCE_FILES}
   Unix/AssemblyCommon.cpp
   Unix/DateTime.cpp

+ 18 - 2
pal/inc/pal.h

@@ -6644,8 +6644,6 @@ PALIMPORT void __cdecl _makepath(char *, const char *, const char *, const char
 PALIMPORT void __cdecl _wmakepath(WCHAR *, const WCHAR *, const WCHAR *, const WCHAR *, const WCHAR *);
 PALIMPORT char * __cdecl _fullpath(char *, const char *, size_t);
 
-PALIMPORT void __cdecl _swab(char *, char *, int);
-
 #ifndef PAL_STDCPP_COMPAT
 PALIMPORT time_t __cdecl time(time_t *);
 
@@ -7101,6 +7099,24 @@ public:
 #define _O_TEXT     0x4000
 #define _O_BINARY   0x8000
 
+ULONG_PTR __stdcall GetCurrentSP();
+
+// xplat-todo: implement me
+#define IsProcessorFeaturePresent(x) false
+
+#if defined(_ARM_)
+#define _ARM_BARRIER_SY 0xF
+#define _InstructionSynchronizationBarrier() __isb(_ARM_BARRIER_SY)
+#endif
+
+#ifndef MAXUINT16
+#define MAXUINT16 ((unsigned short)-1)
+#endif
+
+#ifndef MAXUINT8
+#define MAXUINT8 ((unsigned char)-1)
+#endif
+
 #ifdef  __cplusplus
 }
 #endif

+ 4 - 35
pal/inc/pal_mstypes.h

@@ -85,22 +85,8 @@ extern "C" {
 
 #endif // !_MSC_VER
 
-#ifdef _MSC_VER
-
-#if defined(PAL_IMPLEMENTATION)
-#define PALIMPORT
-#else
-#define PALIMPORT   __declspec(dllimport)
-#endif
-#define PAL_NORETURN __declspec(noreturn)
-
-#else
-
 #define PALIMPORT
 #define PAL_NORETURN    __attribute__((noreturn))
-
-#endif
-
 #define PALAPI      __stdcall
 #define PALAPIV     __cdecl
 
@@ -137,19 +123,6 @@ extern "C" {
 // Misc. type helpers
 ////////////////////////////////////////////////////////////////////////
 
-#ifdef _MSC_VER
-
-// MSVC's way of declaring large integer constants
-// If you define these in one step, without the _HELPER macros, you
-// get extra whitespace when composing these with other concatenating macros.
-#define I64_HELPER(x) x ## i64
-#define I64(x)        I64_HELPER(x)
-
-#define UI64_HELPER(x) x ## ui64
-#define UI64(x)        UI64_HELPER(x)
-
-#else // _MSC_VER
-
 // GCC's way of declaring large integer constants
 // If you define these in one step, without the _HELPER macros, you
 // get extra whitespace when composing these with other concatenating macros.
@@ -159,8 +132,6 @@ extern "C" {
 #define UI64_HELPER(x) x ## ULL
 #define UI64(x)        UI64_HELPER(x)
 
-#endif // _MSC_VER
-
 ////////////////////////////////////////////////////////////////////////
 // Misc. types
 ////////////////////////////////////////////////////////////////////////
@@ -501,8 +472,6 @@ UShortToPtr(
 #define UShortToPtr( us )  ((VOID *)(UINT_PTR)((unsigned short)(s)))
 #endif // !defined(BIT64)
 
-
-
 #else
 
 typedef _W64 __int32 INT_PTR;
@@ -566,7 +535,7 @@ typedef LONG_PTR SSIZE_T, *PSSIZE_T;
 typedef unsigned long size_t;
 typedef long ptrdiff_t;
 #else // !BIT64
-typedef unsigned long size_t;
+typedef unsigned int size_t;
 typedef int ptrdiff_t;
 #endif // !BIT64
 #else
@@ -586,7 +555,7 @@ typedef LONG_PTR LPARAM;
 #endif
 
 // CC uses both char16_t and wchar_t internally
-#if !defined(_WCHAR_T_DEFINED)
+#if !defined(PAL_WCHAR_T_DEFINED)
 #if defined(__cplusplus)
 #undef wchar_t
 #define wchar_t __wchar_16_cpp__
@@ -594,8 +563,8 @@ typedef char16_t wchar_t;
 #else
 typedef unsigned short char16_t;
 #endif // __cplusplus
-#define _WCHAR_T_DEFINED
-#endif // _WCHAR_T_DEFINED
+#define PAL_WCHAR_T_DEFINED
+#endif // PAL_WCHAR_T_DEFINED
 
 typedef char16_t WCHAR;
 #define WCHAR_IS_CHAR16_T 1

+ 0 - 23
pal/inc/rt/safecrt.h

@@ -97,14 +97,6 @@
 #endif
 #endif
 
-/* WCHAR */
-#if defined (SAFECRT_INCLUDE_REDEFINES)
-#if !defined(_WCHAR_T_DEFINED)
-typedef unsigned short WCHAR;
-#define _WCHAR_T_DEFINED
-#endif
-#endif
-
 /* _W64 */
 #if !defined(_W64)
 #if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
@@ -114,18 +106,6 @@ typedef unsigned short WCHAR;
 #endif
 #endif
 
-/* size_t */
-#if defined (SAFECRT_INCLUDE_REDEFINES)
-#if !defined(_SIZE_T_DEFINED)
-#if defined(_WIN64)
-typedef unsigned __int64    size_t;
-#else
-typedef _W64 unsigned int   size_t;
-#endif
-#define _SIZE_T_DEFINED
-#endif
-#endif
-
 /* uintptr_t */
 #if !defined(_UINTPTR_T_DEFINED)
 #if defined(_WIN64)
@@ -371,9 +351,6 @@ void __cdecl _invalid_parameter(const WCHAR *_Message, const WCHAR *_FunctionNam
 #if (_SAFECRT_USE_INLINES || _SAFECRT_IMPL) && !defined(_SAFECRT_DO_NOT_DEFINE_INVALID_PARAMETER)
 
 #ifndef STATUS_INVALID_PARAMETER
-#if defined (SAFECRT_INCLUDE_REDEFINES)
-typedef LONG NTSTATUS;
-#endif
 #define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
 #endif
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 128 - 128
pal/inc/strsafe.h


+ 0 - 4
pal/inc/unixasmmacros.inc

@@ -21,10 +21,6 @@
 #define C_PLTFUNC(name) name@PLT
 #endif
 
-.macro LEAF_END Name, Section
-        LEAF_END_MARKED \Name, \Section
-.endm
-
 .macro END_PROLOGUE
 .endm
 

+ 7 - 3
pal/inc/unixasmmacrosamd64.inc

@@ -3,6 +3,10 @@
 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 
+.macro LEAF_END Name, Section
+        LEAF_END_MARKED \Name, \Section
+.endm
+
 .macro NESTED_ENTRY Name, Section, Handler
         LEAF_ENTRY \Name, \Section
         .ifnc \Handler, NoHandler
@@ -121,16 +125,16 @@ C_FUNC(\Name\()_End):
 .macro save_xmm128_postrsp Reg, Offset
         __Offset = \Offset
         movdqa  xmmword ptr [rsp + __Offset], \Reg
-        // NOTE: We cannot use ".cfi_rel_offset \Reg, __Offset" here, 
+        // NOTE: We cannot use ".cfi_rel_offset \Reg, __Offset" here,
         // the xmm registers are not supported by the libunwind
 .endm
 
 .macro restore_xmm128 Reg, ofs
         __Offset = \ofs
         movdqa          \Reg, xmmword ptr [rsp + __Offset]
-        // NOTE: We cannot use ".cfi_restore \Reg" here, 
+        // NOTE: We cannot use ".cfi_restore \Reg" here,
         // the xmm registers are not supported by the libunwind
-        
+
 .endm
 
 .macro PUSH_CALLEE_SAVED_REGISTERS

+ 272 - 0
pal/inc/unixasmmacrosarm.inc

@@ -0,0 +1,272 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+.macro LEAF_ENTRY Name, Section
+        .thumb_func
+        .global C_FUNC(\Name)
+        .type \Name, %function
+C_FUNC(\Name):
+        .fnstart
+.endm
+
+.macro NESTED_ENTRY Name, Section, Handler
+        LEAF_ENTRY \Name, \Section
+        .ifnc \Handler, NoHandler
+        .personality C_FUNC(\Handler)
+        .endif
+.endm
+
+.macro NESTED_END Name, Section
+        LEAF_END \Name, \Section
+.endm
+
+.macro NESTED_END_MARKED Name, Section
+        LEAF_END_MARKED \Name, \Section
+.endm
+
+.macro PATCH_LABEL Name
+        .thumb_func
+        .global C_FUNC(\Name)
+C_FUNC(\Name):
+.endm
+
+.macro LEAF_END Name, Section
+        .size \Name, .-\Name
+        .fnend
+.endm
+
+.macro LEAF_END_MARKED Name, Section
+        .thumb_func
+        .global C_FUNC(\Name\()_End)
+C_FUNC(\Name\()_End):
+        LEAF_END \Name, \Section
+.endm
+
+.macro PREPARE_EXTERNAL_VAR Name, HelperReg
+        ldr \HelperReg, [pc, #C_FUNC(\Name)@GOTPCREL]
+.endm
+
+.macro push_nonvol_reg Register
+        push \Register
+        .save \Register
+.endm
+
+.macro pop_nonvol_reg Register
+        pop \Register
+.endm
+
+.macro vpush_nonvol_reg Register
+        vpush \Register
+        .vsave \Register
+.endm
+
+.macro vpop_nonvol_reg Register
+        vpop \Register
+.endm
+
+.macro alloc_stack Size
+        sub sp, sp, (\Size)
+        .pad #(\Size)
+.endm
+
+.macro free_stack Size
+        add sp, sp, (\Size)
+        .pad #-(\Size)
+.endm
+
+.macro POP_CALLEE_SAVED_REGISTERS
+        pop_nonvol_reg "{r4-r11, lr}"
+.endm
+
+.macro PUSH_CALLEE_SAVED_REGISTERS
+        push_nonvol_reg "{r4-r11, lr}"
+.endm
+
+.macro push_register Reg
+        push \Reg
+.endm
+
+.macro push_argument_register Reg
+        push_register \Reg
+.endm
+
+.macro PUSH_ARGUMENT_REGISTERS
+        push {r0-r3}
+        .save {r0-r3}
+.endm
+
+.macro pop_register Reg
+        pop \Reg
+.endm
+
+.macro pop_argument_register Reg
+        pop_register \Reg
+.endm
+
+.macro POP_ARGUMENT_REGISTERS
+        pop {r0-r3}
+.endm
+
+// Stack layout:
+//
+// (stack parameters)
+// ...
+// ArgumentRegisters::r3
+// ArgumentRegisters::r2
+// ArgumentRegisters::r1
+// ArgumentRegisters::r0
+// CalleeSavedRegisters::lr
+// CalleeSavedRegisters::r11
+// CalleeSavedRegisters::r10
+// CalleeSavedRegisters::r9
+// CalleeSavedRegisters::r8
+// CalleeSavedRegisters::r7    <- r7
+// CalleeSavedRegisters::r6
+// CalleeSavedRegisters::r5
+// CalleeSavedRegisters::r4    <- __PWTB_StackAlloc, __PWTB_TransitionBlock
+// padding to align float save area
+// d7
+// d6
+// d5
+// d4
+// d3
+// d2
+// d1
+// d0                          <- __PWTB_FloatArgumentRegisters
+.macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, saveFpArgs = 1, pushArgRegs = 0
+
+        __PWTB_FloatArgumentRegisters = \extraLocals
+        __PWTB_SaveFPArgs = \saveFpArgs
+
+        .if (__PWTB_SaveFPArgs == 1)
+                .if ((__PWTB_FloatArgumentRegisters % 8) != 0)
+                __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 4
+                .endif
+
+                __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters + 8 * 8 + 4 // 8 floating point registers + padding
+        .else
+                .if ((__PWTB_FloatArgumentRegisters % 8) == 0)
+                __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 4
+                .endif
+
+                __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
+        .endif
+
+        __PWTB_StackAlloc = __PWTB_TransitionBlock
+
+        .ifnc \pushArgRegs, DoNotPushArgRegs
+                PUSH_ARGUMENT_REGISTERS
+        .endif
+
+        PUSH_CALLEE_SAVED_REGISTERS
+        PROLOG_STACK_SAVE_OFFSET r7, #12
+        // let r7 point the saved r7 in the stack (clang FP style)
+
+        alloc_stack     __PWTB_StackAlloc
+
+        .if (__PWTB_SaveFPArgs == 1)
+                add r6, sp, #(__PWTB_FloatArgumentRegisters)
+                vstm r6, {d0-d7}
+        .endif
+
+        CHECK_STACK_ALIGNMENT
+
+        END_PROLOGUE
+
+.endm
+
+.macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
+
+        free_stack __PWTB_StackAlloc
+        POP_CALLEE_SAVED_REGISTERS
+        free_stack 16
+        bx lr
+
+.endm
+
+.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+
+        .if (__PWTB_SaveFPArgs == 1)
+                add r6, sp, #(__PWTB_FloatArgumentRegisters)
+                vldm r6, {d0-d7}
+        .endif
+
+        free_stack __PWTB_StackAlloc
+        POP_CALLEE_SAVED_REGISTERS
+        POP_ARGUMENT_REGISTERS
+
+.endm
+
+.macro EMIT_BREAKPOINT
+        .inst.w 0xde01
+.endm
+
+.macro PROLOG_PUSH RegList
+        push_nonvol_reg "\RegList"
+.endm
+
+.macro PROLOG_VPUSH RegList
+        vpush_nonvol_reg "\RegList"
+.endm
+
+.macro PROLOG_STACK_SAVE Register
+        .setfp \Register, sp
+        mov \Register, sp
+.endm
+
+.macro PROLOG_STACK_SAVE_OFFSET Register, Offset
+        .setfp \Register, sp, \Offset
+        add \Register, sp, \Offset
+.endm
+
+.macro EPILOG_STACK_FREE Size
+        add sp, sp, \Size
+.endm
+
+.macro EPILOG_STACK_RESTORE Register
+        mov sp, \Register
+.endm
+
+.macro EPILOG_STACK_RESTORE_OFFSET Register, Offset
+        sub sp, \Register, \Offset
+.endm
+
+.macro EPILOG_BRANCH Target
+        b \Target
+.endm
+
+.macro EPILOG_BRANCH_REG reg
+        bx \reg
+.endm
+
+.macro EPILOG_POP RegList
+        pop_nonvol_reg "\RegList"
+.endm
+
+.macro EPILOG_VPOP RegList
+        vpop_nonvol_reg "\RegList"
+.endm
+
+//-----------------------------------------------------------------------------
+// Macro used to check (in debug builds only) whether the stack is 64-bit aligned (a requirement before calling
+// out into C++/OS code). Invoke this directly after your prolog (if the stack frame size is fixed) or directly
+// before a call (if you have a frame pointer and a dynamic stack). A breakpoint will be invoked if the stack
+// is misaligned.
+//
+.macro CHECK_STACK_ALIGNMENT
+
+#ifdef _DEBUG
+        push {r0}
+        add r0, sp, #4
+        tst r0, #7
+        pop {r0}
+        beq 0f
+        EMIT_BREAKPOINT
+0:
+#endif
+.endm

+ 39 - 22
pal/src/CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.12.2)
+cmake_minimum_required(VERSION 3.2)
 
 include_directories(SYSTEM /usr/local/include)
 
@@ -11,17 +11,14 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
 cmake_policy(SET CMP0042 NEW)
 
 # Include directories
-
 include_directories(include)
 
 # Compile options
-
 if(CC_TARGETS_AMD64)
     add_definitions(-D_AMD64_)
 elseif(CC_TARGETS_X86)
     add_definitions(-D__i686__)
-elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
-    set(PAL_CMAKE_PLATFORM_ARCH_ARM 1)
+elseif(CC_TARGETS_ARM)
     add_definitions(-D_ARM_)
 elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
     set(PAL_CMAKE_PLATFORM_ARCH_ARM64 1)
@@ -30,30 +27,19 @@ else()
     clr_unknown_arch()
 endif()
 
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+if(CC_TARGET_OS_ANDROID OR CC_TARGET_OS_LINUX)
   add_definitions(-D__LINUX__=1)
-endif(CMAKE_SYSTEM_NAME STREQUAL Linux)
-
-if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
-  set(PLATFORM_SOURCES
-    arch/i386/activationhandlerwrapper.S
-    arch/i386/context.S
-    arch/i386/dispatchexceptionwrapper.S
-    exception/machexception.cpp
-    exception/machmessage.cpp
-  )
-endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+endif()
 
 add_definitions(-DPLATFORM_UNIX=1)
 add_definitions(-DLP64COMPATIBLE=1)
 add_definitions(-DFEATURE_PAL=1)
-# add_definitions(-DCORECLR=1)
 add_definitions(-DPIC=1)
 add_definitions(-D_FILE_OFFSET_BITS=64)
 if(CC_TARGETS_AMD64)
   add_definitions(-DBIT64=1)
   add_definitions(-D_WIN64=1)
-elseif(PAL_CMAKE_PLATFORM_ARCH_ARM OR CC_TARGETS_X86)
+elseif(CC_TARGETS_ARM OR CC_TARGETS_X86)
   add_definitions(-DBIT32=1)
 elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64)
   add_definitions(-DBIT64=1)
@@ -66,11 +52,33 @@ endif()
 add_compile_options(-fno-builtin)
 add_compile_options(-fPIC)
 
+if(CC_TARGET_OS_OSX)
+  set(PLATFORM_SOURCES
+    exception/machexception.cpp
+    exception/machmessage.cpp
+  )
+endif()
+
 if(CC_TARGETS_AMD64 OR CC_TARGETS_X86)
+  if(CC_TARGET_OS_OSX)
+    set(PLATFORM_SOURCES ${PLATFORM_SOURCES}
+      arch/i386/activationhandlerwrapper.S
+      arch/i386/context.S
+      arch/i386/dispatchexceptionwrapper.S
+    )
+  endif()
   set(ARCH_SOURCES
     arch/i386/context2.S
     arch/i386/debugbreak.S
     arch/i386/processor.cpp
+    arch/i386/asmhelpers.S
+    )
+elseif(CC_TARGETS_ARM)
+  set(ARCH_SOURCES
+    arch/arm/context2.S
+    arch/arm/debugbreak.S
+    arch/arm/processor.cpp
+    arch/arm/asmhelpers.S
     )
 endif()
 
@@ -167,14 +175,23 @@ add_library(Chakra.Pal
   ${ARCH_SOURCES}
 )
 
-if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+if(CC_TARGET_OS_OSX)
   target_link_libraries(Chakra.Pal
     "-framework CoreFoundation"
     "-framework Security"
   )
 else() # Linux
+  if (NOT CC_TARGET_OS_ANDROID)
+    set(PTHREAD pthread)
+  endif()
+
   target_link_libraries(Chakra.Pal
-    pthread
+    ${PTHREAD}
     dl
   )
-endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+  if(CC_TARGET_OS_ANDROID)
+      add_custom_command(TARGET Chakra.Pal POST_BUILD
+          COMMAND ${ANDROID_TOOLCHAIN_DIR}/bin/ranlib ${CMAKE_CURRENT_BINARY_DIR}/libChakra.Pal.a
+      )
+  endif()
+endif()

+ 65 - 0
pal/src/arch/arm/asmconstants.h

@@ -0,0 +1,65 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef __PAL_ARM_ASMCONSTANTS_H__
+#define __PAL_ARM_ASMCONSTANTS_H__
+
+#define CONTEXT_ContextFlags 0
+#define CONTEXT_R0           CONTEXT_ContextFlags+4
+#define CONTEXT_R1           CONTEXT_R0+4
+#define CONTEXT_R2           CONTEXT_R1+4
+#define CONTEXT_R3           CONTEXT_R2+4
+#define CONTEXT_R4           CONTEXT_R3+4
+#define CONTEXT_R5           CONTEXT_R4+4
+#define CONTEXT_R6           CONTEXT_R5+4
+#define CONTEXT_R7           CONTEXT_R6+4
+#define CONTEXT_R8           CONTEXT_R7+4
+#define CONTEXT_R9           CONTEXT_R8+4
+#define CONTEXT_R10          CONTEXT_R9+4
+#define CONTEXT_R11          CONTEXT_R10+4
+#define CONTEXT_R12          CONTEXT_R11+4
+#define CONTEXT_Sp           CONTEXT_R12+4
+#define CONTEXT_Lr           CONTEXT_Sp+4
+#define CONTEXT_Pc           CONTEXT_Lr+4
+#define CONTEXT_Cpsr         CONTEXT_Pc+4
+#define CONTEXT_Fpscr        CONTEXT_Cpsr+4
+#define CONTEXT_Padding      CONTEXT_Fpscr+4
+#define CONTEXT_D0           CONTEXT_Padding+4
+#define CONTEXT_D1           CONTEXT_D0+8
+#define CONTEXT_D2           CONTEXT_D1+8
+#define CONTEXT_D3           CONTEXT_D2+8
+#define CONTEXT_D4           CONTEXT_D3+8
+#define CONTEXT_D5           CONTEXT_D4+8
+#define CONTEXT_D6           CONTEXT_D5+8
+#define CONTEXT_D7           CONTEXT_D6+8
+#define CONTEXT_D8           CONTEXT_D7+8
+#define CONTEXT_D9           CONTEXT_D8+8
+#define CONTEXT_D10          CONTEXT_D9+8
+#define CONTEXT_D11          CONTEXT_D10+8
+#define CONTEXT_D12          CONTEXT_D11+8
+#define CONTEXT_D13          CONTEXT_D12+8
+#define CONTEXT_D14          CONTEXT_D13+8
+#define CONTEXT_D15          CONTEXT_D14+8
+#define CONTEXT_D16          CONTEXT_D15+8
+#define CONTEXT_D17          CONTEXT_D16+8
+#define CONTEXT_D18          CONTEXT_D17+8
+#define CONTEXT_D19          CONTEXT_D18+8
+#define CONTEXT_D20          CONTEXT_D19+8
+#define CONTEXT_D21          CONTEXT_D20+8
+#define CONTEXT_D22          CONTEXT_D21+8
+#define CONTEXT_D23          CONTEXT_D22+8
+#define CONTEXT_D24          CONTEXT_D23+8
+#define CONTEXT_D25          CONTEXT_D24+8
+#define CONTEXT_D26          CONTEXT_D25+8
+#define CONTEXT_D27          CONTEXT_D26+8
+#define CONTEXT_D28          CONTEXT_D27+8
+#define CONTEXT_D29          CONTEXT_D28+8
+#define CONTEXT_D30          CONTEXT_D29+8
+#define CONTEXT_D31          CONTEXT_D30+8
+
+#endif

+ 30 - 0
pal/src/arch/arm/asmhelpers.S

@@ -0,0 +1,30 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// ==++==
+//
+
+//
+// ==--==
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+.syntax unified
+.thumb
+
+// LPVOID __stdcall GetCurrentIP(void)//
+    LEAF_ENTRY GetCurrentIP, _TEXT
+        mov     r0, lr
+        bx      lr
+    LEAF_END GetCurrentIP, _TEXT
+
+// LPVOID __stdcall GetCurrentSP(void)//
+    LEAF_ENTRY GetCurrentSP, _TEXT
+        mov     r0, sp
+        bx      lr
+    LEAF_END GetCurrentSP, _TEXT

+ 178 - 0
pal/src/arch/arm/context2.S

@@ -0,0 +1,178 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+// Implementation of _CONTEXT_CaptureContext for the ARM platform.
+// This function is processor dependent.  It is used by exception handling,
+// and is always apply to the current thread.
+//
+
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+.syntax unified
+.thumb
+
+#define CONTEXT_ARM     0x00200000
+
+#define CONTEXT_CONTROL 1 // Sp, Lr, Pc, Cpsr
+#define CONTEXT_INTEGER 2 // R0-R12
+#define CONTEXT_SEGMENTS 4 //
+#define CONTEXT_FLOATING_POINT 8
+#define CONTEXT_DEBUG_REGISTERS 16 //
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
+
+
+// Incoming:
+//  r0: Context*
+//
+LEAF_ENTRY CONTEXT_CaptureContext, _TEXT
+    // Ensure we save these registers
+    push {r4-r11}
+    // Save processor flags before calling any of the following 'test' instructions
+    // because they will modify state of some flags
+    push {r1}
+    mrs r1, apsr // Get APSR - equivalent to eflags
+    push {r1} // Save APSR
+    END_PROLOGUE
+
+    push {r2}
+    ldr r2, [r0, #(CONTEXT_ContextFlags)]
+    tst r2, #(CONTEXT_INTEGER)
+    pop {r2}
+
+    // Add 4 to stack so we point at R1, pop, then sub 8 to point at APSR
+    add sp, sp, #4
+    pop {r1}
+    sub sp, sp, #8
+
+    itttt ne
+    strne r0, [r0, #(CONTEXT_R0)]
+    addne r0, CONTEXT_R1
+    stmiane r0, {r1-r12}
+    subne r0, CONTEXT_R1
+
+    ldr r2, [r0, #(CONTEXT_ContextFlags)]
+    tst r2, #(CONTEXT_CONTROL)
+
+    ittt ne
+    addne sp, sp, #(10*4) // This needs to put the stack in the same state as it started
+    strne sp, [r0, #(CONTEXT_Sp)]
+    subne sp, sp, #(10*4)
+
+    itt ne
+    strne lr, [r0, #(CONTEXT_Lr)]
+    strne lr, [r0, #(CONTEXT_Pc)]
+
+    // Get the APSR pushed onto the stack at the start
+    pop {r1}
+    it ne
+    strne r1, [r0, #(CONTEXT_Cpsr)]
+
+    ldr r2, [r0, #(CONTEXT_ContextFlags)]
+    tst r2, #(CONTEXT_FLOATING_POINT)
+
+    itt ne
+    vmrsne r3, fpscr
+    strne r3, [r0, #(CONTEXT_Fpscr)]
+
+    itttt ne
+    addne r0, CONTEXT_D0
+    vstmiane r0!, {d0-d15}
+    vstmiane r0!, {d16-d31}
+    subne r0, CONTEXT_D31
+
+    // Make sure sp is restored
+    add sp, sp, #4
+
+    // Restore callee saved registers
+    pop {r4-r11}
+    bx lr
+LEAF_END CONTEXT_CaptureContext, _TEXT
+
+// Incoming:
+//  R0: Context*
+//
+LEAF_ENTRY RtlCaptureContext, _TEXT
+    push {r1}
+    mov r1, #0
+    orr r1, r1, #CONTEXT_ARM
+    orr r1, r1, #CONTEXT_INTEGER
+    orr r1, r1, #CONTEXT_CONTROL
+    orr r1, r1, #CONTEXT_FLOATING_POINT
+    str r1, [r0, #(CONTEXT_ContextFlags)]
+    pop {r1}
+    b C_FUNC(CONTEXT_CaptureContext)
+LEAF_END RtlCaptureContext, _TEXT
+
+// Incoming:
+//  r0: Context*
+//  r1: Exception*
+//
+LEAF_ENTRY RtlRestoreContext, _TEXT
+    END_PROLOGUE
+
+    ldr r2, [r0, #(CONTEXT_ContextFlags)]
+    tst r2, #(CONTEXT_FLOATING_POINT)
+
+    itttt ne
+    addne r0, CONTEXT_D0
+    vldmiane r0!, {d0-d15}
+    vldmiane r0, {d16-d31}
+    subne r0, CONTEXT_D16
+
+    itt ne
+    ldrne r3, [r0, #(CONTEXT_Fpscr)]
+    vmrsne r3, FPSCR
+
+    ldr r2, [r0, #(CONTEXT_ContextFlags)]
+    tst r2, #(CONTEXT_CONTROL)
+
+    it eq
+    beq LOCAL_LABEL(No_Restore_CONTEXT_CONTROL)
+
+    ldr r2, [r0, #(CONTEXT_ContextFlags)]
+    tst r2, #(CONTEXT_INTEGER)
+
+    it eq
+    beq LOCAL_LABEL(No_Restore_CONTEXT_INTEGER)
+
+    ldr R2, [r0, #(CONTEXT_Cpsr)]
+    msr APSR, r2
+
+    // Ideally, we would like to use `ldmia r0, {r0-r12, sp, lr, pc}` here,
+    // but clang 3.6 and later, as per ARM recommendation, disallows using
+    // Sp in the register list, and Pc and Lr simultaneously.
+    // So we are going to use the IPC register r12 to copy Sp, Lr and Pc
+    // which should be ok -- TODO: Is this really ok?
+    add r12, r0, CONTEXT_R0
+    ldm r12, {r0-r11}
+    ldr sp, [r12, #(CONTEXT_Sp - (CONTEXT_R0))]
+    ldr lr, [r12, #(CONTEXT_Lr - (CONTEXT_R0))]
+    ldr pc, [r12, #(CONTEXT_Pc - (CONTEXT_R0))]
+
+LOCAL_LABEL(No_Restore_CONTEXT_INTEGER):
+
+    ldr r2, [r0, #(CONTEXT_Cpsr)]
+    msr APSR, r2
+
+    ldr sp, [r0, #(CONTEXT_Sp)]
+    ldr lr, [r0, #(CONTEXT_Lr)]
+    ldr pc, [r0, #(CONTEXT_Pc)]
+
+LOCAL_LABEL(No_Restore_CONTEXT_CONTROL):
+    ldr r2, [r0, #(CONTEXT_ContextFlags)]
+    tst r2, #(CONTEXT_INTEGER)
+
+    itt ne
+    addne r0, CONTEXT_R0
+    ldmiane r0, {r0-r12}
+
+    sub sp, sp, #4
+    bx lr
+LEAF_END RtlRestoreContext, _TEXT

+ 17 - 0
pal/src/arch/arm/debugbreak.S

@@ -0,0 +1,17 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "unixasmmacros.inc"
+
+.syntax unified
+.thumb
+
+LEAF_ENTRY DBG_DebugBreak, _TEXT
+    EMIT_BREAKPOINT
+    bx lr
+LEAF_END_MARKED DBG_DebugBreak, _TEXT

+ 34 - 0
pal/src/arch/arm/exceptionhelper.S

@@ -0,0 +1,34 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+.syntax unified
+.thumb
+
+// EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex);
+LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
+    // Ported from src/pal/src/arch/amd64/exceptionhelper.S
+    push_nonvol_reg {r7} /* FP. x64-RBP */
+
+    ldr	r4,	[r0, #(CONTEXT_R4)]
+    ldr	r5,	[r0, #(CONTEXT_R5)]
+    ldr	r6,	[r0, #(CONTEXT_R6)]
+    ldr	r7,	[r0, #(CONTEXT_R7)]
+    ldr	r8,	[r0, #(CONTEXT_R8)]
+    ldr	r9,	[r0, #(CONTEXT_R9)]
+    ldr	r10,	[r0, #(CONTEXT_R10)]
+    ldr	r11,	[r0, #(CONTEXT_R11)]
+    ldr	sp,	[r0, #(CONTEXT_Sp)]
+    ldr	lr,	[r0, #(CONTEXT_Pc)]
+
+    // The PAL_SEHException pointer
+    mov	r0,	r1
+    b	EXTERNAL_C_FUNC(ThrowExceptionHelper)
+LEAF_END ThrowExceptionFromContextInternal, _TEXT

+ 45 - 0
pal/src/arch/arm/processor.cpp

@@ -0,0 +1,45 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*++
+
+
+
+Module Name:
+
+    processor.cpp
+
+Abstract:
+
+    Implementation of processor related functions for the ARM
+    platform. These functions are processor dependent.
+
+
+
+--*/
+
+#include "pal/palinternal.h"
+
+/*++
+Function:
+YieldProcessor
+
+The YieldProcessor function signals to the processor to give resources
+to threads that are waiting for them. This macro is only effective on
+processors that support technology allowing multiple threads running
+on a single processor, such as Intel's Hyper-Threading technology.
+
+--*/
+void
+PALAPI
+YieldProcessor(
+    VOID)
+{
+	// Pretty sure ARM has no useful function here?
+    return;
+}

+ 42 - 0
pal/src/arch/i386/asmhelpers.S

@@ -0,0 +1,42 @@
+// -------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+// -------------------------------------------------------------------------------------------------------
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// ==++==
+//
+
+//
+// ==--==
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+#ifdef __i686__
+//
+// UINT_PTR __stdcall GetCurrentIP(void);
+LEAF_ENTRY GetCurrentIP, _TEXT
+    mov     eax, [esp]
+    ret
+LEAF_END GetCurrentIP, _TEXT
+
+// LPVOID __stdcall GetCurrentSP(void);
+LEAF_ENTRY GetCurrentSP, _TEXT
+    mov     eax, esp
+    ret
+LEAF_END GetCurrentSP, _TEXT
+#else
+LEAF_ENTRY GetCurrentSP, _TEXT
+        mov rax, rsp
+        add rax, 8
+        ret
+LEAF_END GetCurrentSP, _TEXT
+
+LEAF_ENTRY GetCurrentIP, _TEXT
+        mov rax, [rsp]
+        ret
+LEAF_END GetCurrentIP, _TEXT
+#endif

+ 129 - 1
pal/src/configure.cmake

@@ -1,3 +1,7 @@
+# xplat-todo: Cleanup this file!
+# we have `feature detection` for direct compilation target and manual entries for cross-compilation below
+if (NOT CC_TARGET_OS_ANDROID)
+
 include(CheckCXXSourceCompiles)
 include(CheckCXXSourceRuns)
 include(CheckCXXSymbolExists)
@@ -916,5 +920,129 @@ if(NOT NO_ICU_PATH_GIVEN)
     message(FATAL_ERROR "Cannot find ICU. Try installing libicu-dev or the appropriate packages for your platform. You may also disable icu/unicode with '--no-icu' argument")
   endif()
 endif()
-
+else() # ANDROID
+  set(HAVE_IEEEFP_H 0)
+  set(HAVE_ALLOCA_H 1)
+  set(HAVE_SYS_VMPARAM_H 0)
+  set(HAVE_PROCFS_H 0)
+  set(HAVE_CRT_EXTERNS_H 0)
+  set(HAVE_SYS_TIME_H 1)
+  set(HAVE_PTHREAD_NP_H 0)
+  set(HAVE_SYS_LWP_H 0)
+  set(HAVE_LIBUUID_H 1)
+  set(HAVE_RUNETYPE_H 0)
+  set(HAVE_KQUEUE 0)
+  set(HAVE_GETPWUID_R 1)
+  set(HAVE_PTHREAD_SUSPEND 1)
+  set(HAVE_PTHREAD_SUSPEND_NP 1)
+  set(HAVE_PTHREAD_CONTINUE 1)
+  # -DHAVE_PTHREAD_RESUME_NP 1
+  # -DHAVE_PTHREAD_CONTINUE_NP 1
+  # -DHAVE_PTHREAD_ATTR_GET_NP 1
+  set(HAVE_PTHREAD_GETATTR_NP 1)
+  set(HAVE_PTHREAD_SIGQUEUE 1)
+  set(HAVE_SIGRETURN 1)
+  set(HAVE__THREAD_SYS_SIGRETURN 1)
+  set(HAVE_COPYSIGN 1)
+  set(HAVE_FSYNC 1)
+  set(HAVE_FUTIMES 0)
+  set(HAVE_UTIMES 1)
+  set(HAVE_SYSCTL 0)
+  set(HAVE_SYSCONF 0)
+  set(HAVE_LOCALTIME_R 1)
+  set(HAVE_GMTIME_R 1)
+  set(HAVE_TIMEGM 1)
+  set(HAVE_POLL 1)
+  set(HAVE_STATVFS 1)
+  set(HAVE_THREAD_SELF 0)
+  set(HAVE__LWP_SELF 0)
+  set(HAVE_VM_ALLOCATE 0)
+  set(HAVE_VM_READ 0)
+  set(HAS_SYSV_SEMAPHORES 0)
+  set(HAS_PTHREAD_MUTEXES 1)
+  # -DHAVE_TTRACE
+  set(HAVE_STAT_TIMESPEC 0)
+  set(HAVE_STAT_NSEC 0)
+  set(HAVE_TM_GMTOFF 1)
+  # -DHAVE_PT_REGS 1)
+  # -DHAVE_GREGSET_T
+  set(HAVE_SIGINFO_T 1)
+  set(HAVE_UCONTEXT_T 1)
+  set(HAVE_PTHREAD_RWLOCK_T 1)
+  set(HAVE_PRWATCH_T 0)
+  set(HAVE_YIELD_SYSCALL 0)
+  set(HAVE_INFTIM 0)
+  set(HAVE_CHAR_BIT 1)
+  # -DUSER_H_DEFINES_DEBUG 1
+  # -DHAVE__SC_PHYS_PAGES 1)
+  # -DHAVE__SC_AVPHYS_PAGES
+  # -DREALPATH_SUPPORTS_NONEXISTENT_FILES
+  # -DSSCANF_CANNOT_HANDLE_MISSING_EXPONENT
+  # -DSSCANF_SUPPORT_ll
+  # -DHAVE_LARGE_SNPRINTF_SUPPORT 1)
+  # -DHAVE_BROKEN_FIFO_SELECT 1)
+  # -DHAVE_BROKEN_FIFO_KEVENT 1)
+  # -DHAS_FTRUNCATE_LENGTH_ISSUE
+  # -DHAVE_SCHED_GET_PRIORITY 1)
+  # -DHAVE_SCHED_GETCPU 1)
+  set(HAVE_WORKING_GETTIMEOFDAY 1)
+  set(HAVE_WORKING_CLOCK_GETTIME 1)
+  set(HAVE_CLOCK_MONOTONIC 1)
+  set(HAVE_CLOCK_MONOTONIC_COARSE 1)
+  set(HAVE_MACH_ABSOLUTE_TIME 0)
+  set(HAVE_CLOCK_THREAD_CPUTIME 1)
+  # -DSTATVFS64_PROTOTYPE_BROKEN
+  # -DHAVE_MMAP_DEV_ZERO
+  # -DMMAP_IGNORES_HINT
+  # -DMMAP_ANON_IGNORES_PROTECTION
+  set(MMAP_DOESNOT_ALLOW_REMAP 1)
+  # -DONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS
+  # -DPTHREAD_CREATE_MODIFIES_ERRNO 1)
+  # -DSEM_INIT_MODIFIES_ERRNO 1)
+  # -DHAVE_PROCFS_CTL
+  set(HAVE_COMPATIBLE_ACOS 1)
+  set(HAVE_COMPATIBLE_ASIN 1)
+  set(HAVE_COMPATIBLE_ATAN2 1)
+  set(HAVE_COMPATIBLE_EXP 1)
+  set(HAVE_COMPATIBLE_LOG 1)
+  set(HAVE_COMPATIBLE_LOG10 1)
+  set(UNGETC_NOT_RETURN_EOF 1)
+  set(HAS_POSIX_SEMAPHORES 1)
+  # -DGETPWUID_R_SETS_ERRNO
+  # -DFILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL
+  # -DPAL_THREAD_PRIORITY_MIN 0
+  # -DPAL_THREAD_PRIORITY_MAX 0
+  # -DDEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX
+  # -DSYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING
+  # -DERROR_FUNC_FOR_GLOB_HAS_FIXED_PARAMS
+  # -DHAS_FTRUNCATE_LENGTH_ISSUE
+  # -DUNWIND_CONTEXT_IS_UCONTEXT_T
+  # -DCHECK_TRACE_SPECIFIERS 0)
+  # -DPROCFS_MEM_NAME=""
+  # -DHAVE_GETHRTIME 1)
+  set(HAVE_LOWERCASE_ISO_NAME 1)
+  set(HAVE_READ_REAL_TIME 1)
+  set(HAVE_UNDERSCORE_ISO_NAME 0)
+  set(MKSTEMP64_IS_USED_INSTEAD_OF_MKSTEMP 0)
+  set(NEED_DLCOMPAT 0)
+  # set(OPEN64_IS_USED_INSTEAD_OF_OPEN 0)
+  set(PAL_IGNORE_NORMAL_THREAD_PRIORITY 0)
+  set(SELF_SUSPEND_FAILS_WITH_NATIVE_SUSPENSION 0)
+  set(SET_SCHEDPARAM_NEEDS_PRIVS 0)
+  set(SIGWAIT_FAILS_WHEN_PASSED_FULL_SIGSET 0)
+  set(SYNCHMGR_PIPE_BASED_THREAD_BLOCKING 0)
+  set(WRITE_0_BYTES_HANGS_TTY 0)
+  set(HAVE_FTRUNCATE_LARGE_LENGTH_SUPPORT 1)
+  set(HAVE_MACH_EXCEPTIONS 0)
+  set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
+  set(PAL_PTRACE "ptrace((cmd), (pid), (void*)(addr), (data))")
+  set(PAL_PT_ATTACH PTRACE_ATTACH)
+  set(PAL_PT_DETACH PTRACE_DETACH)
+  set(PAL_PT_READ_D PTRACE_PEEKDATA)
+  set(PAL_PT_WRITE_D PTRACE_POKEDATA)
+  set(JA_JP_LOCALE_NAME ja_JP_LOCALE_NOT_FOUND)
+  set(KO_KR_LOCALE_NAME ko_KR_LOCALE_NOT_FOUND)
+  set(ZH_TW_LOCALE_NAME zh_TW_LOCALE_NOT_FOUND)
+  set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
+endif()
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)

+ 23 - 100
pal/src/cruntime/file.cpp

@@ -1,6 +1,6 @@
 //
 // Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 
 /*++
@@ -40,7 +40,7 @@ SET_DEFAULT_DEBUG_CHANNEL(CRT);
 
 /* Global variables storing the std streams.*/
 PAL_FILE PAL_Stdout PAL_GLOBAL;
-PAL_FILE PAL_Stdin PAL_GLOBAL; 
+PAL_FILE PAL_Stdin PAL_GLOBAL;
 PAL_FILE PAL_Stderr PAL_GLOBAL;
 
 /*++
@@ -99,7 +99,7 @@ static LPSTR MapFileOpenModes(LPSTR str , BOOL * bTextMode)
     }
 
     /* The PAL behaves differently for some Windows file open modes:
-    
+
     c, n, S, R, and T: these are all hints to the system that aren't supported
     by the PAL. Since the user cannot depend on this behavior, it's safe to
     simply ignore these modes.
@@ -107,14 +107,14 @@ static LPSTR MapFileOpenModes(LPSTR str , BOOL * bTextMode)
     D: specifies a file as temporary. This file is expected to be deleted when
     the last file descriptor is closed. The PAL does not support this behavior
     and asserts when this mode is used.
-    
+
     t: represents opening in text mode. Calls to fdopen on Unix don't accept
-    't' so it is silently stripped out. However, the PAL supports the mode by 
-    having the PAL wrappers do the translation of CR-LF to LF and vice versa. 
-    
+    't' so it is silently stripped out. However, the PAL supports the mode by
+    having the PAL wrappers do the translation of CR-LF to LF and vice versa.
+
     t vs. b: To get binary mode, you must explicitly use 'b'. If neither mode
-    is specified on Windows, the default mode is defined by the global 
-    variable _fmode. The PAL simply defaults to text mode. After examining 
+    is specified on Windows, the default mode is defined by the global
+    variable _fmode. The PAL simply defaults to text mode. After examining
     CLR usage patterns, the PAL behavior seems acceptable. */
 
     /* Check if the mode specifies deleting the temporary file
@@ -192,44 +192,6 @@ static BOOL WriteOnlyMode(FILE* pFile)
 }
 #endif //UNGETC_NOT_RETURN_EOF
 
-/*++
-Function:
-  _getw
-
-Gets an integer from a stream.
-
-Return Value
-
-_getw returns the integer value read. A return value of EOF indicates
-either an error or end of file. However, because the EOF value is also
-a legitimate integer value, use feof or ferror to verify an
-end-of-file or error condition.
-
-Parameter
-
-file  Pointer to FILE structure
-
---*/
-int
-__cdecl
-_getw(PAL_FILE *f)
-{
-    INT ret = 0;
-    
-    PERF_ENTRY(_getw);
-    ENTRY("_getw (f=%p)\n", f);
-
-    _ASSERTE(f != NULL);
-
-    CLEARERR(f);
-    
-    ret = getw( f->bsdFilePtr );
-    LOGEXIT( "returning %d\n", ret );
-    PERF_EXIT(_getw);
-    
-    return ret;
-}
-
 
 /*++
 Function:
@@ -328,7 +290,7 @@ PAL_fopen(const char * fileName, const char * mode)
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
             goto done;
         }
-        
+
         FILEDosToUnixPathA( UnixFileName );
 
         /*I am not checking for the case where stat fails
@@ -445,45 +407,6 @@ _wfsopen(
     return NULL;
 }
 
-/*++
-Function:
-  _putw
-
-Writes an integer to a stream.
-
-Return Value
-
-_putw returns the value written. A return value of EOF may indicate an
-error. Because EOF is also a legitimate integer value, use ferror to
-verify an error.
-
-Parameters
-
-c     Binary integer to be output
-file  Pointer to FILE structure
-
---*/
-int
-__cdecl
-_putw(int c, PAL_FILE *f)
-{
-    INT ret = 0;
-
-    PERF_ENTRY(_putw);
-    ENTRY("_putw (c=0x%x, f=%p)\n", c, f);
-
-    _ASSERTE(f != NULL);
-
-    CLEARERR(f);
- 
-    ret = putw(c,  f->bsdFilePtr );
-    LOGEXIT( "returning %d\n", ret );
-    PERF_EXIT(_putw);
-
-    return ret;
-}
-
-
 /*++
 Function
     PAL_get_stdout.
@@ -556,7 +479,7 @@ int __cdecl PAL__close(int handle)
  {
     return fflush(NULL);
  }
- 
+
 char16_t *
 __cdecl
 PAL_fgetws(char16_t *s, int n, PAL_FILE *f)
@@ -583,7 +506,7 @@ PAL_fread(void * buffer, size_t size, size_t count, PAL_FILE * f)
     PERF_ENTRY(fread);
     ENTRY( "fread( buffer=%p, size=%d, count=%d, f=%p )\n",
            buffer, size, count, f );
-	
+
     _ASSERTE(f != NULL);
 
     CLEARERR(f);
@@ -620,7 +543,7 @@ PAL_fread(void * buffer, size_t size, size_t count, PAL_FILE * f)
         }
         nReadBytes = i;
     }
-	
+
 done:
     LOGEXIT( "fread returning size_t %d\n", nReadBytes );
     PERF_EXIT(fread);
@@ -700,11 +623,11 @@ PAL_setbuf(PAL_FILE * f, char * buffer)
 {
     PERF_ENTRY(setbuf);
     ENTRY( "setbuf( %p, %p )\n", f, buffer );
-    
+
     _ASSERTE(f != NULL);
 
     setbuf( f->bsdFilePtr, buffer );
-    
+
     LOGEXIT( "setbuf\n" );
     PERF_EXIT(setbuf);
 }
@@ -814,11 +737,11 @@ PAL_ftell(PAL_FILE * f)
         lRetVal = -1;
     }
 #endif
-	
+
     LOGEXIT( "ftell returning %ld\n", lRetVal );
     PERF_EXIT(ftell);
     /* This explicit cast to LONG is used to silence any potential warnings
-    due to implicitly casting the native long lRetVal to LONG when returning. */    
+    due to implicitly casting the native long lRetVal to LONG when returning. */
     return (LONG)lRetVal;
 }
 
@@ -848,7 +771,7 @@ PAL_fgetpos (
 
     PERF_ENTRY(fgetpos);
     ENTRY("fgetpos( f=%p, pos=%p )\n", f, pos);
-    
+
     _ASSERTE(f != NULL);
     _ASSERTE(pos != NULL);
 
@@ -861,7 +784,7 @@ PAL_fgetpos (
         ERROR ("Error: NULL pos pointer\n");
         errno = EINVAL;
     }
-  
+
     LOGEXIT( "fgetpos returning error code %d, pos %d\n", nRetVal, pos ? *pos : 0);
     PERF_EXIT(fgetpos);
     return nRetVal;
@@ -906,7 +829,7 @@ PAL_fsetpos (
         ERROR ("Error: NULL pos pointer\n");
         errno = EINVAL;
     }
-  
+
     LOGEXIT( "fsetpos returning error code %d\n", nRetVal);
     PERF_EXIT(fsetpos);
     return nRetVal;
@@ -1033,11 +956,11 @@ PAL_setvbuf(PAL_FILE *f, char *buf, int type, size_t size)
 
     PERF_ENTRY(setvbuf);
     ENTRY( "setvbuf( %p, %p, %d, %ul )\n", f, buf, type, size);
-    
+
     _ASSERTE(f != NULL);
-    
+
     nRetVal = setvbuf(f->bsdFilePtr, buf, type, size);
-    
+
     LOGEXIT( "setvbuf returning %d\n", nRetVal );
     PERF_EXIT(setvbuf);
     return nRetVal;

+ 35 - 90
pal/src/cruntime/string.cpp

@@ -1,6 +1,6 @@
 //
 // Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 
 /*++
@@ -40,19 +40,19 @@ Function:
 compare at most count characters from two strings, ignoring case
 
 The strnicmp() function compares, with case insensitivity, at most count
-characters from s1 to s2. All uppercase characters from s1 and s2 are 
+characters from s1 to s2. All uppercase characters from s1 and s2 are
 mapped to lowercase for the purposes of doing the comparison.
 
 Returns:
 
 Value Meaning
 
-< 0   s1 is less than s2 
-0     s1 is equal to s2 
+< 0   s1 is less than s2
+0     s1 is equal to s2
 > 0   s1 is greater than s2
 
 --*/
-int 
+int
 __cdecl
 _strnicmp( const char *s1, const char *s2, size_t count )
 {
@@ -83,15 +83,15 @@ Returns:
 
 Value Meaning
 
-< 0   s1 is less than s2 
-0     s1 is equal to s2 
+< 0   s1 is less than s2
+0     s1 is equal to s2
 > 0   s1 is greater than s2
 
 --*/
-int 
+int
 __cdecl
 _stricmp(
-         const char *s1, 
+         const char *s1,
          const char *s2)
 {
     int ret;
@@ -131,7 +131,7 @@ current locale. Other characters are not affected. For more
 information on LC_CTYPE, see setlocale.
 
 --*/
-char *  
+char *
 __cdecl
 _strlwr(
         char *str)
@@ -145,68 +145,14 @@ _strlwr(
     {
         *str = tolower(*str);
         str++;
-    } 
-   
+    }
+
     LOGEXIT("_strlwr returning char* %p (%s)\n", orig?orig:"NULL", orig?orig:"NULL");
     PERF_EXIT(_strlwr);
     return orig;
 }
 
 
-/*++
-Function:
-  _swab
-
-Swaps bytes.
-
-Return Value
-
-None
-
-Parameters
-
-src        Data to be copied and swapped
-dest       Storage location for swapped data
-n          Number of bytes to be copied and swapped
-
-Remarks
-
-The _swab function copies n bytes from src, swaps each pair of
-adjacent bytes, and stores the result at dest. The integer n should be
-an even number to allow for swapping. _swab is typically used to
-prepare binary data for transfer to a machine that uses a different
-byte order.
-
-Example
-
-char from[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-char   to[] = "..........................";
-
-printf("Before:\n%s\n%s\n\n", from, to);
-_swab(from, to, strlen(from));
-printf("After:\n%s\n%s\n\n", from, to);
-
-Before:
-ABCDEFGHIJKLMNOPQRSTUVWXYZ
-..........................
-
-After:
-ABCDEFGHIJKLMNOPQRSTUVWXYZ
-BADCFEHGJILKNMPORQTSVUXWZY
-
---*/
-void
-__cdecl
-_swab(char *src, char *dest, int n)
-{
-    PERF_ENTRY(_swab);
-    ENTRY("_swab (src=%p (%s), dest=%p (%s), n=%d)\n", src?src:"NULL", src?src:"NULL", dest?dest:"NULL", dest?dest:"NULL", n);
-    swab(src, dest, n);
-    LOGEXIT("_swab returning\n");
-    PERF_EXIT(_swab);
-}
-
-
 /*++
 Function:
   PAL_strtoul
@@ -243,30 +189,30 @@ Notes :
     tests indicate that other whitespace characters (newline, carriage return,
     etc) are also accepted. This matches the behavior on Unix systems.
 
-    For strtoul, we need to check if the value to be returned 
+    For strtoul, we need to check if the value to be returned
     is outside the 32 bit range. If so, the returned value needs to be set
-    as appropriate, according to the MSDN pages and in all instances errno 
-    must be set to ERANGE (The one exception is converting a string 
+    as appropriate, according to the MSDN pages and in all instances errno
+    must be set to ERANGE (The one exception is converting a string
     representing a negative value to unsigned long).
     Note that on 64 bit Windows, long's are still 32 bit. Thus, to match
     Windows behavior, we must return long's in the 32 bit range.
     --*/
 
-/* The use of ULONG is by design, to ensure that a 32 bit value is always 
+/* The use of ULONG is by design, to ensure that a 32 bit value is always
 returned from this function. If "unsigned long" is used instead of ULONG,
 then a 64 bit value could be returned on 64 bit platforms like HP-UX, thus
 breaking Windows behavior. */
-ULONG 
-__cdecl 
+ULONG
+__cdecl
 PAL_strtoul(const char *szNumber, char **pszEnd, int nBase)
 {
     unsigned long ulResult;
-    
+
     PERF_ENTRY(strtoul);
-    ENTRY("strtoul (szNumber=%p (%s), pszEnd=%p, nBase=%d)\n", 
-        szNumber?szNumber:"NULL", 
+    ENTRY("strtoul (szNumber=%p (%s), pszEnd=%p, nBase=%d)\n",
         szNumber?szNumber:"NULL",
-        pszEnd, 
+        szNumber?szNumber:"NULL",
+        pszEnd,
         nBase);
 
     ulResult = strtoul(szNumber, pszEnd, nBase);
@@ -279,7 +225,7 @@ PAL_strtoul(const char *szNumber, char **pszEnd, int nBase)
         {
 	    ch = *szNumber++;
         }
-        /* If the string represents a positive number that is greater than 
+        /* If the string represents a positive number that is greater than
             _UI32_MAX, set errno to ERANGE. Otherwise, don't set errno
             to match Windows behavior. */
         if (ch != '-')
@@ -292,17 +238,17 @@ PAL_strtoul(const char *szNumber, char **pszEnd, int nBase)
 
     LOGEXIT("strtoul returning unsigned long %lu\n", ulResult);
     PERF_EXIT(wcstoul);
-    
-    /* When returning unsigned long res from this function, it will be 
+
+    /* When returning unsigned long res from this function, it will be
         implicitly cast to ULONG. This handles situations where a string that
         represents a negative number is passed in to strtoul. The Windows
         behavior is analogous to taking the binary equivalent of the negative
         value and treating it as a positive number. Returning a ULONG from
         this function, as opposed to native unsigned long, allows us to match
         this behavior. The explicit cast to ULONG below is used to silence any
-        potential warnings due to the implicit casting.  */    
+        potential warnings due to the implicit casting.  */
     return (ULONG)ulResult;
-    
+
 }
 
 
@@ -314,7 +260,7 @@ Convert string to a long value.
 
 Return Value
 
-atol returns the converted value, if any. In the case of overflow, 
+atol returns the converted value, if any. In the case of overflow,
 the return value is undefined.
 
 Parameters
@@ -322,21 +268,21 @@ Parameters
 szNumber  Null-terminated string to convert to a LONG
 --*/
 
-/* The use of LONG is by design, to ensure that a 32 bit value is always 
-returned from this function. If "long" is used instead of LONG, then a 64 bit 
-value could be returned on 64 bit platforms like HP-UX, thus breaking 
+/* The use of LONG is by design, to ensure that a 32 bit value is always
+returned from this function. If "long" is used instead of LONG, then a 64 bit
+value could be returned on 64 bit platforms like HP-UX, thus breaking
 Windows behavior. */
-LONG 
+LONG
 __cdecl
 PAL_atol(const char *szNumber)
 {
     long lResult;
 
     PERF_ENTRY(atol);
-    ENTRY("atol (szNumber=%p (%s))\n", 
+    ENTRY("atol (szNumber=%p (%s))\n",
         szNumber?szNumber:"NULL"
         );
-    
+
     lResult = atol(szNumber);
 
     LOGEXIT("atol returning long %ld\n", (LONG)lResult);
@@ -344,6 +290,5 @@ PAL_atol(const char *szNumber)
     /* This explicit cast to LONG is used to silence any potential warnings
         due to implicitly casting the native long lResult to LONG when returning. */
     return (LONG)lResult;
-    
-}
 
+}

+ 0 - 1
pal/src/include/pal/file.h

@@ -38,7 +38,6 @@ typedef struct _find_handle
 
     char   dir[_MAX_DIR];
     char   fname[MAX_PATH_FNAME]; /* includes extension */
-    glob_t gGlob;
     char   **next;
 } find_obj;
 

+ 0 - 2
pal/src/include/pal/palinternal.h

@@ -212,7 +212,6 @@ function_name() to call the system's implementation
 #define atof DUMMY_atof
 #define time DUMMY_time
 #define tm PAL_tm
-#define size_t DUMMY_size_t
 #define time_t PAL_time_t
 #define va_list DUMMY_va_list
 #define abs DUMMY_abs
@@ -573,7 +572,6 @@ function_name() to call the system's implementation
 #include <pwd.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <glob.h>
 
 #ifdef __APPLE__
 

+ 1 - 1
pal/src/loader/module.cpp

@@ -57,7 +57,7 @@ Abstract:
 #include <sys/types.h>
 #include <sys/mman.h>
 
-#if defined(__LINUX__)
+#if defined(__LINUX__) && !defined(__ANDROID__)
 #include <gnu/lib-names.h>
 #endif
 

+ 21 - 21
pal/src/locale/unicode.cpp

@@ -1,6 +1,6 @@
 //
 // Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 
 /*++
@@ -38,7 +38,7 @@ Revision History:
 
 #include <pthread.h>
 #include <locale.h>
-#ifndef __APPLE__
+#if !defined(__APPLE__) && !defined(__ANDROID__)
 #include <libintl.h>
 #endif // __APPLE__
 #include <errno.h>
@@ -148,7 +148,7 @@ BOOL GetUnicodeData(INT nUnicodeValue, UnicodeDataRec *pDataRec)
     {
         UnicodeDataRec *dataRec;
         INT nNumOfChars = UNICODE_DATA_SIZE;
-        dataRec = (UnicodeDataRec *) bsearch(&nUnicodeValue, UnicodeData, nNumOfChars, 
+        dataRec = (UnicodeDataRec *) bsearch(&nUnicodeValue, UnicodeData, nNumOfChars,
                        sizeof(UnicodeDataRec), UnicodeDataComp);
         if (dataRec == NULL)
         {
@@ -164,16 +164,16 @@ BOOL GetUnicodeData(INT nUnicodeValue, UnicodeDataRec *pDataRec)
 }
 #endif /* !HAVE_COREFOUNDATION */
 
-/*++ 
+/*++
 Function:
 CODEPAGEGetData
-    
+
     IN UINT CodePage - The code page the caller
     is attempting to retrieve data on.
-    
+
     Returns a pointer to structure, NULL otherwise.
 --*/
-const CP_MAPPING * 
+const CP_MAPPING *
 CODEPAGEGetData( IN UINT CodePage )
 {
     UINT nSize = sizeof( CP_TO_NATIVE_TABLE ) / sizeof( CP_TO_NATIVE_TABLE[ 0 ] );
@@ -193,7 +193,7 @@ CODEPAGEGetData( IN UINT CodePage )
         }
         nIndex++;
     }
-    return NULL;    
+    return NULL;
 }
 
 #if HAVE_COREFOUNDATION
@@ -331,7 +331,7 @@ GetConsoleCP(
     UINT nRet = 0;
     PERF_ENTRY(GetConsoleCP);
     ENTRY("GetConsoleCP()\n");
-     
+
     nRet = GetACP();
 
     LOGEXIT("GetConsoleCP returns UINT %d\n", nRet );
@@ -403,7 +403,7 @@ IsValidCodePage(
         retval = (NULL != CODEPAGEGetData( CodePage ));
         break;
     }
-       
+
     LOGEXIT("IsValidCodePage returns BOOL %d\n",retval);
     PERF_EXIT(IsValidCodePage);
     return retval;
@@ -533,7 +533,7 @@ GetCPInfo(
 {
     const CP_MAPPING * lpStruct = NULL;
     BOOL bRet = FALSE;
-     
+
     PERF_ENTRY(GetCPInfo);
     ENTRY("GetCPInfo(CodePage=%hu, lpCPInfo=%p)\n", CodePage, lpCPInfo);
 
@@ -626,9 +626,9 @@ IsDBCSLeadByteEx(
         {
             goto done;
         }
-         
+
         /*check if the given char is in one of the lead byte ranges*/
-        if( cpinfo.LeadByte[i] <= TestChar && TestChar<= cpinfo.LeadByte[i+1] ) 
+        if( cpinfo.LeadByte[i] <= TestChar && TestChar<= cpinfo.LeadByte[i+1] )
         {
             bRet = TRUE;
             goto done;
@@ -822,14 +822,14 @@ WideCharToMultiByte(
           lpDefaultChar, lpUsedDefaultChar);
 
     if (dwFlags & ~WC_NO_BEST_FIT_CHARS)
-    {  
+    {
         ERROR("dwFlags %d invalid\n", dwFlags);
         SetLastError(ERROR_INVALID_FLAGS);
         goto EXIT;
     }
 
     // No special action is needed for WC_NO_BEST_FIT_CHARS. The default
-    // behavior of this API on Unix is not to find the best fit for a unicode 
+    // behavior of this API on Unix is not to find the best fit for a unicode
     // character that does not map directly into a code point in the given
     // code page. The best fit functionality is not available in wctomb on Unix
     // and is better left unimplemented for security reasons anyway.
@@ -856,7 +856,7 @@ WideCharToMultiByte(
     {
         if (cchWideChar == -1)
         {
-            cchWideChar = PAL_wcslen(lpWideCharStr) + 1; 
+            cchWideChar = PAL_wcslen(lpWideCharStr) + 1;
         }
         retval = UnicodeToUTF8(lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte);
         goto EXIT;
@@ -941,12 +941,12 @@ EXIT:
     /* Flag the cases when WC_NO_BEST_FIT_CHARS was not specified
      * but we found characters that had to be replaced with default
      * characters. Note that Windows would have attempted to find
-     * best fit characters under these conditions and that could pose 
-     * a security risk. 
+     * best fit characters under these conditions and that could pose
+     * a security risk.
      */
     _ASSERT_MSG((dwFlags & WC_NO_BEST_FIT_CHARS) || !usedDefaultChar,
           "WideCharToMultiByte found a string which doesn't round trip: (%p)%S "
-          "and WC_NO_BEST_FIT_CHARS was not specified\n", 
+          "and WC_NO_BEST_FIT_CHARS was not specified\n",
           lpWideCharStr, lpWideCharStr);
 
     LOGEXIT("WideCharToMultiByte returns INT %d\n", retval);
@@ -972,12 +972,12 @@ PAL_GetResourceString(
         IN int cchWideChar
       )
 {
-#ifndef __APPLE__
+#if !defined(__APPLE__) && !defined(__ANDROID__)
     // NOTE: dgettext returns the key if it fails to locate the appropriate
     // resource. In our case, that will be the English string.
     LPCSTR resourceString = dgettext(lpDomain, lpResourceStr);
 #else // __APPLE__
-    // UNIXTODO: Implement for OSX using the native localization API 
+    // UNIXTODO: Implement for OSX using the native localization API
 
     // This is a temporary solution until we add the real native resource support.
     LPCSTR resourceString = lpResourceStr;

+ 10 - 7
pal/src/misc/sysinfo.cpp

@@ -29,7 +29,7 @@ Revision History:
 #include <sys/types.h>
 #if HAVE_SYSCTL
 #include <sys/sysctl.h>
-#elif !HAVE_SYSCONF
+#elif !HAVE_SYSCONF && !defined(__ANDROID__)
 #error Either sysctl or sysconf is required for GetSystemInfo.
 #endif
 
@@ -82,7 +82,7 @@ SET_DEFAULT_DEBUG_CHANNEL(MISC);
 #define SYSCONF_PAGES _SC_AVPHYS_PAGES
 #elif HAVE_SYSCONF && HAVE__SC_PHYS_PAGES
 #define SYSCONF_PAGES _SC_PHYS_PAGES
-#else
+#elif !defined(__ANDROID__)
 #error Dont know how to get page-size on this architecture!
 #endif
 #endif // __APPLE__
@@ -258,7 +258,7 @@ GlobalMemoryStatusEx(
         lpBuffer->ullTotalPhys = (DWORDLONG)physical_memory;
         fRetVal = TRUE;
     }
-#elif // HAVE_SYSINFO
+#else // HAVE_SYSINFO
     // TODO: implement getting memory details via sysinfo. On Linux, it provides swap file details that
     // we can use to fill in the xxxPageFile members.
 
@@ -268,11 +268,15 @@ GlobalMemoryStatusEx(
     // We do this only when we have the total physical memory available.
     if (lpBuffer->ullTotalPhys > 0)
     {
-#ifndef __APPLE__
+#if defined(__ANDROID__)
+        lpBuffer->ullAvailPhys = lpBuffer->ullTotalPhys; // xplat-todo: fix this
+        INT64 used_memory = lpBuffer->ullTotalPhys - lpBuffer->ullAvailPhys;
+        lpBuffer->dwMemoryLoad = (DWORD)((used_memory * 100) / lpBuffer->ullTotalPhys);
+#elif defined(__LINUX__)
         lpBuffer->ullAvailPhys = sysconf(SYSCONF_PAGES) * sysconf(_SC_PAGE_SIZE);
         INT64 used_memory = lpBuffer->ullTotalPhys - lpBuffer->ullAvailPhys;
         lpBuffer->dwMemoryLoad = (DWORD)((used_memory * 100) / lpBuffer->ullTotalPhys);
-#else
+#elif defined(__APPLE__)
         vm_size_t page_size;
         mach_port_t mach_port;
         mach_msg_type_number_t count;
@@ -345,7 +349,7 @@ PAL_GetLogicalProcessorCacheSizeFromOS()
 {
     size_t cacheSize = 0;
 
-#if HAVE_SYSCONF && defined(__LINUX__)
+#if HAVE_SYSCONF && defined(__LINUX__) && !defined(__ANDROID__)
     cacheSize = max(cacheSize, sysconf(_SC_LEVEL1_DCACHE_SIZE));
     cacheSize = max(cacheSize, sysconf(_SC_LEVEL1_ICACHE_SIZE));
     cacheSize = max(cacheSize, sysconf(_SC_LEVEL2_CACHE_SIZE));
@@ -355,4 +359,3 @@ PAL_GetLogicalProcessorCacheSizeFromOS()
 
     return cacheSize;
 }
-

+ 1 - 9
pal/src/thread/pal_thread.cpp

@@ -2886,15 +2886,7 @@ bool IsAddressOnStack(ULONG_PTR address)
         s_cachedThreadStackHighLimit = highLimit;
     }
 
-    ULONG_PTR currentStackPtr = 0;
-
-#ifdef _AMD64_
-    asm("mov %%rsp, %0;":"=r"(currentStackPtr));
-#elif defined(__i686__)
-    asm("mov %%esp, %0;":"=r"(currentStackPtr));
-#else
-#error "Implement this!!"
-#endif
+    ULONG_PTR currentStackPtr = GetCurrentSP();
 
     if (currentStackPtr <= address && address < s_cachedThreadStackHighLimit)
     {

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels