aboutsummaryrefslogtreecommitdiff
path: root/jerry-libc
diff options
context:
space:
mode:
authorSung-Jae Lee <sjlee@mail.com>2015-09-15 09:43:03 +0900
committerSung-Jae Lee <sjlee@mail.com>2015-09-15 10:31:57 +0900
commit01f66f7b04afdc6355a78c85557656ac33b23418 (patch)
tree7fd12a1fe6347bfce9cd58521fd1b345445c6867 /jerry-libc
parent311cc65b33a150c1eed055f4a96670922d5478ca (diff)
Enable build on Mac OS X with clang
* Add build target 'darwin' * Modify compiler options to work with clang * Support 'jerry-libc' on Mac OS X For MPU target build, install `gcc-arm-none-eabi` tool chain using `Homebrew` as following. ```` brew tap PX4/homebrew-px4 brew update brew install gcc-arm-none-eabi ```` https://pixhawk.org/dev/toolchain_installation_mac JerryScript-DCO-1.0-Signed-off-by: Sung-Jae Lee sjlee@mail.com
Diffstat (limited to 'jerry-libc')
-rw-r--r--jerry-libc/CMakeLists.txt8
-rw-r--r--jerry-libc/target/darwin/jerry-asm.S56
-rw-r--r--jerry-libc/target/darwin/jerry-libc-target.c386
3 files changed, 450 insertions, 0 deletions
diff --git a/jerry-libc/CMakeLists.txt b/jerry-libc/CMakeLists.txt
index 19791eff..adbc746a 100644
--- a/jerry-libc/CMakeLists.txt
+++ b/jerry-libc/CMakeLists.txt
@@ -40,6 +40,8 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}")
# Platform-specific
# Linux
set(DEFINES_LIBC_LINUX __TARGET_HOST)
+ # Darwin
+ set(DEFINES_LIBC_DARWIN __TARGET_HOST)
# MCU
set(DEFINES_LIBC_MCU __TARGET_MCU)
# stm32f3
@@ -57,6 +59,9 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}")
# Linux
set(INCLUDE_THIRD_PARTY_LINUX )
+ # Darwin
+ set(INCLUDE_THIRD_PARTY_DARWIN )
+
# MCU
# STM32F3
set(INCLUDE_THIRD_PARTY_MCU_STM32F3
@@ -74,6 +79,9 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}")
# Linux
file(GLOB SOURCE_LIBC_LINUX target/linux/*.c target/linux/*.S)
+ # Darwin
+ file(GLOB SOURCE_LIBC_DARWIN target/darwin/*.c target/darwin/*.S)
+
# MCU
# stm32f3
file(GLOB SOURCE_LIBC_MCU_STM32F3 target/mcu-stubs/*.c target/mcu-stubs/*.S)
diff --git a/jerry-libc/target/darwin/jerry-asm.S b/jerry-libc/target/darwin/jerry-asm.S
new file mode 100644
index 00000000..7219f4fe
--- /dev/null
+++ b/jerry-libc/target/darwin/jerry-asm.S
@@ -0,0 +1,56 @@
+#ifdef __TARGET_HOST_x64
+# include "arch/x86-64.h"
+#elif defined (__TARGET_HOST_x86)
+# include "arch/x86-32.h"
+#elif defined (__TARGET_HOST_ARMv7)
+# include "arch/arm-v7.h"
+#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
+# error "!__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7"
+#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
+
+.global _start
+_start:
+ _START
+
+.global syscall_0_asm
+syscall_0_asm:
+ SYSCALL_0
+
+.global syscall_1_asm
+syscall_1_asm:
+ SYSCALL_1
+
+.global syscall_2_asm
+syscall_2_asm:
+ SYSCALL_2
+
+.global syscall_3_asm
+syscall_3_asm:
+ SYSCALL_3
+
+/**
+ * setjmp (jmp_buf env)
+ *
+ * See also:
+ * longjmp
+ *
+ * @return 0 - if returns from direct call,
+ * nonzero - if returns after longjmp.
+ */
+.global setjmp
+setjmp:
+ _SETJMP
+
+/**
+ * longjmp (jmp_buf env, int val)
+ *
+ * Note:
+ * if val is not 0, then it would be returned from setjmp,
+ * otherwise - 0 would be returned.
+ *
+ * See also:
+ * setjmp
+ */
+.global longjmp
+longjmp:
+ _LONGJMP
diff --git a/jerry-libc/target/darwin/jerry-libc-target.c b/jerry-libc/target/darwin/jerry-libc-target.c
new file mode 100644
index 00000000..6004af15
--- /dev/null
+++ b/jerry-libc/target/darwin/jerry-libc-target.c
@@ -0,0 +1,386 @@
+/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Jerry libc platform-specific functions darwin implementation
+ */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "jerry-libc-defs.h"
+
+LIBC_UNREACHABLE_STUB_FOR (int raise (int sig_no __attr_unused___))
+
+/**
+ * Exit program with ERR_SYSCALL if syscall_ret_val is negative
+ */
+#define LIBC_EXIT_ON_ERROR(syscall_ret_val) \
+ if ((syscall_ret_val) < 0) \
+{ \
+ libc_fatal ("Syscall", __FILE__, __func__, __LINE__); \
+}
+
+static long int syscall_0 (long int syscall_no);
+static long int syscall_1 (long int syscall_no, long int arg1);
+static long int syscall_2 (long int syscall_no, long int arg1, long int arg2);
+static long int syscall_3 (long int syscall_no, long int arg1, long int arg2, long int arg3);
+
+extern long int syscall_0_asm (long int syscall_no);
+extern long int syscall_1_asm (long int syscall_no, long int arg1);
+extern long int syscall_2_asm (long int syscall_no, long int arg1, long int arg2);
+extern long int syscall_3_asm (long int syscall_no, long int arg1, long int arg2, long int arg3);
+
+/**
+ * System call with no argument.
+ *
+ * @return syscall's return value
+ */
+static __attr_noinline___ long int
+syscall_0 (long int syscall_no) /**< syscall number */
+{
+ long int ret = syscall_0_asm (syscall_no);
+
+ LIBC_EXIT_ON_ERROR (ret);
+
+ return ret;
+} /* syscall_0 */
+
+/**
+ * System call with one argument.
+ *
+ * @return syscall's return value
+ */
+static __attr_noinline___ long int
+syscall_1 (long int syscall_no, /**< syscall number */
+ long int arg1) /**< argument */
+{
+ long int ret = syscall_1_asm (syscall_no, arg1);
+
+ LIBC_EXIT_ON_ERROR (ret);
+
+ return ret;
+} /* syscall_1 */
+
+/**
+ * System call with two arguments.
+ *
+ * @return syscall's return value
+ */
+static __attr_noinline___ long int
+syscall_2 (long int syscall_no, /**< syscall number */
+ long int arg1, /**< first argument */
+ long int arg2) /**< second argument */
+{
+ long int ret = syscall_2_asm (syscall_no, arg1, arg2);
+
+ LIBC_EXIT_ON_ERROR (ret);
+
+ return ret;
+} /* syscall_2 */
+
+/**
+ * System call with three arguments.
+ *
+ * @return syscall's return value
+ */
+static __attr_noinline___ long int
+syscall_3 (long int syscall_no, /**< syscall number */
+ long int arg1, /**< first argument */
+ long int arg2, /**< second argument */
+ long int arg3) /**< third argument */
+{
+ long int ret = syscall_3_asm (syscall_no, arg1, arg2, arg3);
+
+ LIBC_EXIT_ON_ERROR (ret);
+
+ return ret;
+} /* syscall_3 */
+
+/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
+int
+putchar (int c)
+{
+ fwrite (&c, 1, sizeof (char), stdout);
+
+ return c;
+} /* putchar */
+
+/**
+ * Output specified string
+ */
+int
+puts (const char *s) /**< string to print */
+{
+ while (*s)
+ {
+ putchar (*s);
+
+ s++;
+ }
+
+ return 0;
+} /* puts */
+
+/**
+ * Exit - cause normal process termination with specified status code
+ */
+void __attr_noreturn___ __attr_used___
+exit (int status) /**< status code */
+{
+ syscall_1 (SYS_close, (long int)stdin);
+ syscall_1 (SYS_close, (long int)stdout);
+ syscall_1 (SYS_close, (long int)stderr);
+
+ syscall_1 (SYS_exit, status);
+
+ while (true)
+ {
+ /* unreachable */
+ }
+} /* exit */
+
+/**
+ * Abort current process, producing an abnormal program termination.
+ * The function raises the SIGABRT signal.
+ */
+void __attr_noreturn___ __attr_used___
+abort (void)
+{
+ syscall_1 (SYS_close, (long int)stdin);
+ syscall_1 (SYS_close, (long int)stdout);
+ syscall_1 (SYS_close, (long int)stderr);
+
+ syscall_2 (SYS_kill, syscall_0 (SYS_getpid), SIGABRT);
+
+ while (true)
+ {
+ /* unreachable */
+ }
+} /* abort */
+
+/**
+ * fopen
+ *
+ * @return FILE pointer - upon successful completion,
+ * NULL - otherwise
+ */
+FILE*
+fopen (const char *path, /**< file path */
+ const char *mode) /**< file open mode */
+{
+ bool may_read = false;
+ bool may_write = false;
+ bool truncate = false;
+ bool create_if_not_exist = false;
+ bool position_at_end = false;
+
+ LIBC_ASSERT (path != NULL && mode != NULL);
+ LIBC_ASSERT (mode[1] == '+' || mode[1] == '\0');
+
+ switch (mode[0])
+ {
+ case 'r':
+ {
+ may_read = true;
+ may_write = (mode[1] == '+');
+ break;
+ }
+ case 'w':
+ {
+ may_write = true;
+ truncate = true;
+ create_if_not_exist = true;
+ may_read = (mode[1] == '+');
+ break;
+ }
+ case 'a':
+ {
+ may_write = true;
+ position_at_end = true;
+ create_if_not_exist = true;
+ if (mode[1] == '+')
+ {
+ /* Not supported */
+ LIBC_UNREACHABLE ();
+ }
+ break;
+ }
+ default:
+ {
+ LIBC_UNREACHABLE ();
+ }
+ }
+
+ int flags = 0;
+ int access = S_IRUSR | S_IWUSR;
+ if (may_read && !may_write)
+ {
+ flags = O_RDONLY;
+ }
+ else if (!may_read && may_write)
+ {
+ flags = O_WRONLY;
+ }
+ else
+ {
+ LIBC_ASSERT (may_read && may_write);
+
+ flags = O_RDWR;
+ }
+
+ if (truncate)
+ {
+ flags |= O_TRUNC;
+ }
+
+ if (create_if_not_exist)
+ {
+ flags |= O_CREAT;
+ }
+
+ if (position_at_end)
+ {
+ flags |= O_APPEND;
+ }
+
+ long int ret = syscall_3 (SYS_open, (long int) path, flags, access);
+
+ return (void*) (uintptr_t) (ret);
+} /* fopen */
+
+/**
+ * The rewind () function sets the file position indicator
+ * for the stream pointed to by STREAM to the beginning of the file.
+ */
+void
+rewind (FILE *stream) /**< stream pointer */
+{
+ syscall_3 (SYS_lseek, (long int) stream, 0, SEEK_SET);
+} /* rewind */
+
+/**
+ * fclose
+ *
+ * @return 0 - upon successful completion,
+ * non-zero value - otherwise.
+ */
+int
+fclose (FILE *fp) /**< stream pointer */
+{
+ syscall_2 (SYS_close, (long int)fp, 0);
+
+ return 0;
+} /* fclose */
+
+/**
+ * fseek
+ */
+int
+fseek (FILE * fp, /**< stream pointer */
+ long offset, /**< offset */
+ int whence) /**< specifies position type
+ * to add offset to */
+{
+ syscall_3 (SYS_lseek, (long int)fp, offset, whence);
+
+ return 0;
+} /* fseek */
+
+/**
+ * ftell
+ */
+long
+ftell (FILE * fp) /**< stream pointer */
+{
+ long int ret = syscall_3 (SYS_lseek, (long int)fp, 0, SEEK_CUR);
+
+ return ret;
+} /* ftell */
+
+/**
+ * fread
+ *
+ * @return number of elements read
+ */
+size_t
+fread (void *ptr, /**< address of buffer to read to */
+ size_t size, /**< size of elements to read */
+ size_t nmemb, /**< number of elements to read */
+ FILE *stream) /**< stream pointer */
+{
+ long int ret;
+ size_t bytes_read = 0;
+
+ if (size == 0)
+ {
+ return 0;
+ }
+
+ do
+ {
+ ret = syscall_3 (SYS_read,
+ (long int) stream,
+ (long int) ((uint8_t*) ptr + bytes_read),
+ (long int) (size * nmemb - bytes_read));
+
+ bytes_read += (size_t)ret;
+ }
+ while (bytes_read != size * nmemb && ret != 0);
+
+ return bytes_read / size;
+} /* fread */
+
+/**
+ * fwrite
+ *
+ * @return number of elements written
+ */
+size_t
+fwrite (const void *ptr, /**< data to write */
+ size_t size, /**< size of elements to write */
+ size_t nmemb, /**< number of elements */
+ FILE *stream) /**< stream pointer */
+{
+ size_t bytes_written = 0;
+
+ if (size == 0)
+ {
+ return 0;
+ }
+
+ do
+ {
+ long int ret = syscall_3 (SYS_write,
+ (long int) stream,
+ (long int) ((uint8_t*) ptr + bytes_written),
+ (long int) (size * nmemb - bytes_written));
+
+ bytes_written += (size_t)ret;
+ }
+ while (bytes_written != size * nmemb);
+
+ return bytes_written / size;
+} /* fwrite */
+