/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "jsnativestack.h"

#ifdef XP_WIN
# include "jswin.h"

#elif defined(XP_OS2)
# define INCL_DOSPROCESS
# include <os2.h>

#elif defined(XP_MACOSX) || defined(DARWIN) || defined(XP_UNIX)
# include <pthread.h>

# if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#  include <pthread_np.h>
# endif

# if defined(ANDROID)
#  include <unistd.h>
#  include <sys/types.h>
# endif

#elif defined(STARBOARD)
# include "starboard/memory.h"
#else
# error "Unsupported platform"

#endif

#if defined(STARBOARD)
void *
js::GetNativeStackBaseImpl()
{
    void* stackHigh;
    void* stackLow;
    SbMemoryGetStackBounds(&stackHigh, &stackLow);
# if JS_STACK_GROWTH_DIRECTION > 0
    return stackLow;
# else
    return stackHigh;
# endif
}
#elif defined(XP_WIN)

void *
js::GetNativeStackBaseImpl()
{
# if defined(_M_IX86) && defined(_MSC_VER)
    /*
     * offset 0x18 from the FS segment register gives a pointer to
     * the thread information block for the current thread
     */
    NT_TIB* pTib;
    __asm {
        MOV EAX, FS:[18h]
        MOV pTib, EAX
    }
    return static_cast<void*>(pTib->StackBase);

# elif defined(_M_X64)
    PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
    return reinterpret_cast<void*>(pTib->StackBase);

# elif defined(_WIN32) && defined(__GNUC__)
    NT_TIB* pTib;
    asm ("movl %%fs:0x18, %0\n" : "=r" (pTib));
    return static_cast<void*>(pTib->StackBase);

# endif
}

#elif defined(SOLARIS)

#include <ucontext.h>

JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);

void *
js::GetNativeStackBaseImpl()
{
    stack_t st;
    stack_getbounds(&st);
    return static_cast<char*>(st.ss_sp) + st.ss_size;
}

#elif defined(AIX)

#include <ucontext.h>

JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);

void *
js::GetNativeStackBaseImpl()
{
    ucontext_t context;
    getcontext(&context);
    return static_cast<char*>(context.uc_stack.ss_sp) +
        context.uc_stack.ss_size;
}

#elif defined(XP_OS2)

void *
js::GetNativeStackBaseImpl()
{
    PTIB  ptib;
    PPIB  ppib;

    DosGetInfoBlocks(&ptib, &ppib);
    return ptib->tib_pstacklimit;
}

#else /* XP_UNIX */

void *
js::GetNativeStackBaseImpl()
{
    pthread_t thread = pthread_self();
# if defined(XP_MACOSX) || defined(DARWIN)
    return pthread_get_stackaddr_np(thread);

# else
    pthread_attr_t sattr;
    pthread_attr_init(&sattr);
#  if defined(__OpenBSD__)
    stack_t ss;
#  elif defined(PTHREAD_NP_H) || defined(_PTHREAD_NP_H_) || defined(NETBSD)
    /* e.g. on FreeBSD 4.8 or newer, neundorf@kde.org */
    pthread_attr_get_np(thread, &sattr);
#  else
    /*
     * FIXME: this function is non-portable;
     * other POSIX systems may have different np alternatives
     */
    pthread_getattr_np(thread, &sattr);
#  endif

    void *stackBase = 0;
    size_t stackSize = 0;
    int rc;
# if defined(__OpenBSD__)
    rc = pthread_stackseg_np(pthread_self(), &ss);
    stackBase = (void*)((size_t) ss.ss_sp - ss.ss_size);
    stackSize = ss.ss_size;
# elif defined(ANDROID)
    if (gettid() == getpid()) {
        // bionic's pthread_attr_getstack doesn't tell the truth for the main
        // thread (see bug 846670). So we scan /proc/self/maps to find the
        // segment which contains the stack.
        rc = -1;
        FILE *fs = fopen("/proc/self/maps", "r");
        if (fs) {
            char line[100];
            unsigned long stackAddr = (unsigned long)&sattr;
            while (fgets(line, sizeof(line), fs) != NULL) {
                unsigned long stackStart;
                unsigned long stackEnd;
                if (sscanf(line, "%lx-%lx ", &stackStart, &stackEnd) == 2 &&
                    stackAddr >= stackStart && stackAddr < stackEnd) {
                    stackBase = (void *)stackStart;
                    stackSize = stackEnd - stackStart;
                    rc = 0;
                    break;
                }
            }
            fclose(fs);
        }
    } else
        // For non main-threads pthread allocates the stack itself so it tells
        // the truth.
        rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
# else
    rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
# endif
    if (rc)
        MOZ_CRASH();
    JS_ASSERT(stackBase);
    pthread_attr_destroy(&sattr);

#  if JS_STACK_GROWTH_DIRECTION > 0
    return stackBase;
#  else
    return static_cast<char*>(stackBase) + stackSize;
#  endif
# endif
}

#endif /* !XP_WIN */
