Force 16 byte stack alignment on JNI method invocations on x86
Reviewed By: dcolascione Differential Revision: D2989293 fb-gh-sync-id: 9140ced55ef0b8a73fdc03a6d307af87cd2335ef shipit-source-id: 9140ced55ef0b8a73fdc03a6d307af87cd2335ef
This commit is contained in:
parent
d3f2081d90
commit
5df3eeb723
|
@ -1,15 +0,0 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __i386__
|
||||
// The Android x86 ABI states that the NDK toolchain assumes 16 byte stack
|
||||
// alignment: http://developer.android.com/ndk/guides/x86.html JSC checks for
|
||||
// stack alignment, and fails with SIGTRAP if it is not. Empirically, the
|
||||
// google android x86 emulator does not provide this alignment, and so JSC
|
||||
// calls may crash. All checked calls go through here, so the attribute here
|
||||
// is added to force alignment and prevent crashes.
|
||||
#define ALIGN_STACK __attribute__((force_align_arg_pointer))
|
||||
#else
|
||||
#define ALIGN_STACK
|
||||
#endif
|
|
@ -65,7 +65,6 @@ react_library(
|
|||
'JSCMemory.h',
|
||||
],
|
||||
exported_headers = [
|
||||
'AlignStack.h',
|
||||
'Bridge.h',
|
||||
'ExecutorToken.h',
|
||||
'ExecutorTokenFactory.h',
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include "AlignStack.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
@ -18,13 +16,11 @@ struct JsException : std::runtime_error {
|
|||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
ALIGN_STACK
|
||||
inline void throwJSExecutionException(const char* msg) {
|
||||
throw JsException(msg);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
ALIGN_STACK
|
||||
inline void throwJSExecutionException(const char* fmt, Args... args) {
|
||||
int msgSize = snprintf(nullptr, 0, fmt, args...);
|
||||
msgSize = std::min(512, msgSize + 1);
|
||||
|
@ -36,16 +32,16 @@ inline void throwJSExecutionException(const char* fmt, Args... args) {
|
|||
void installGlobalFunction(
|
||||
JSGlobalContextRef ctx,
|
||||
const char* name,
|
||||
JSObjectCallAsFunctionCallback callback) ALIGN_STACK;
|
||||
JSObjectCallAsFunctionCallback callback);
|
||||
|
||||
JSValueRef makeJSCException(
|
||||
JSContextRef ctx,
|
||||
const char* exception_text) ALIGN_STACK;
|
||||
const char* exception_text);
|
||||
|
||||
JSValueRef evaluateScript(
|
||||
JSContextRef ctx,
|
||||
JSStringRef script,
|
||||
JSStringRef sourceURL,
|
||||
const char* cachePath = nullptr) ALIGN_STACK;
|
||||
const char* cachePath = nullptr);
|
||||
|
||||
} }
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include "noncopyable.h"
|
||||
|
||||
#include "AlignStack.h"
|
||||
|
||||
#if WITH_FBJSCEXTENSIONS
|
||||
#include <jsc_stringref.h>
|
||||
#endif
|
||||
|
@ -28,15 +26,15 @@ class Context;
|
|||
|
||||
class String : public noncopyable {
|
||||
public:
|
||||
explicit String(const char* utf8) ALIGN_STACK :
|
||||
explicit String(const char* utf8) :
|
||||
m_string(Adopt, JSStringCreateWithUTF8CString(utf8))
|
||||
{}
|
||||
|
||||
String(String&& other) ALIGN_STACK :
|
||||
String(String&& other) :
|
||||
m_string(Adopt, other.m_string.leakRef())
|
||||
{}
|
||||
|
||||
String(const String& other) ALIGN_STACK :
|
||||
String(const String& other) :
|
||||
m_string(other.m_string)
|
||||
{}
|
||||
|
||||
|
@ -45,16 +43,16 @@ public:
|
|||
}
|
||||
|
||||
// Length in characters
|
||||
size_t length() const ALIGN_STACK {
|
||||
size_t length() const {
|
||||
return JSStringGetLength(m_string.get());
|
||||
}
|
||||
|
||||
// Length in bytes of a null-terminated utf8 encoded value
|
||||
size_t utf8Size() const ALIGN_STACK {
|
||||
size_t utf8Size() const {
|
||||
return JSStringGetMaximumUTF8CStringSize(m_string.get());
|
||||
}
|
||||
|
||||
std::string str() const ALIGN_STACK {
|
||||
std::string str() const {
|
||||
size_t reserved = utf8Size();
|
||||
char* bytes = new char[reserved];
|
||||
size_t length = JSStringGetUTF8CString(m_string.get(), bytes, reserved) - 1;
|
||||
|
@ -63,11 +61,11 @@ public:
|
|||
}
|
||||
|
||||
// Assumes that utf8 is null terminated
|
||||
bool equals(const char* utf8) ALIGN_STACK {
|
||||
bool equals(const char* utf8) {
|
||||
return JSStringIsEqualToUTF8CString(m_string.get(), utf8);
|
||||
}
|
||||
|
||||
static String createExpectingAscii(std::string const &utf8) ALIGN_STACK {
|
||||
static String createExpectingAscii(std::string const &utf8) {
|
||||
#if WITH_FBJSCEXTENSIONS
|
||||
return String(Adopt, JSStringCreateWithUTF8CStringExpectAscii(utf8.c_str(), utf8.size()));
|
||||
#else
|
||||
|
@ -84,11 +82,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
explicit String(JSStringRef string) ALIGN_STACK :
|
||||
explicit String(JSStringRef string) :
|
||||
m_string(string)
|
||||
{}
|
||||
|
||||
String(AdoptTag tag, JSStringRef string) ALIGN_STACK :
|
||||
String(AdoptTag tag, JSStringRef string) :
|
||||
m_string(tag, string)
|
||||
{}
|
||||
|
||||
|
@ -110,7 +108,7 @@ public:
|
|||
other.m_isProtected = false;
|
||||
}
|
||||
|
||||
~Object() ALIGN_STACK {
|
||||
~Object() {
|
||||
if (m_isProtected && m_obj) {
|
||||
JSValueUnprotect(m_context, m_obj);
|
||||
}
|
||||
|
@ -122,28 +120,28 @@ public:
|
|||
|
||||
operator Value() const;
|
||||
|
||||
bool isFunction() const ALIGN_STACK {
|
||||
bool isFunction() const {
|
||||
return JSObjectIsFunction(m_context, m_obj);
|
||||
}
|
||||
|
||||
Value callAsFunction(int nArgs, JSValueRef args[]) ALIGN_STACK;
|
||||
Value callAsFunction(int nArgs, JSValueRef args[]);
|
||||
|
||||
Value getProperty(const String& propName) const ALIGN_STACK;
|
||||
Value getProperty(const String& propName) const;
|
||||
Value getProperty(const char *propName) const;
|
||||
Value getPropertyAtIndex(unsigned index) const ALIGN_STACK;
|
||||
void setProperty(const String& propName, const Value& value) const ALIGN_STACK;
|
||||
Value getPropertyAtIndex(unsigned index) const;
|
||||
void setProperty(const String& propName, const Value& value) const;
|
||||
void setProperty(const char *propName, const Value& value) const;
|
||||
std::vector<std::string> getPropertyNames() const ALIGN_STACK;
|
||||
std::unordered_map<std::string, std::string> toJSONMap() const ALIGN_STACK;
|
||||
std::vector<std::string> getPropertyNames() const;
|
||||
std::unordered_map<std::string, std::string> toJSONMap() const;
|
||||
|
||||
void makeProtected() ALIGN_STACK {
|
||||
void makeProtected() {
|
||||
if (!m_isProtected && m_obj) {
|
||||
JSValueProtect(m_context, m_obj);
|
||||
m_isProtected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static Object getGlobalObject(JSContextRef ctx) ALIGN_STACK {
|
||||
static Object getGlobalObject(JSContextRef ctx) {
|
||||
auto globalObj = JSContextGetGlobalObject(ctx);
|
||||
return Object(ctx, globalObj);
|
||||
}
|
||||
|
@ -151,7 +149,7 @@ public:
|
|||
/**
|
||||
* Creates an instance of the default object class.
|
||||
*/
|
||||
static Object create(JSContextRef ctx) ALIGN_STACK;
|
||||
static Object create(JSContextRef ctx);
|
||||
|
||||
private:
|
||||
JSContextRef m_context;
|
||||
|
@ -168,27 +166,27 @@ public:
|
|||
return m_value;
|
||||
}
|
||||
|
||||
bool isBoolean() const ALIGN_STACK {
|
||||
bool isBoolean() const {
|
||||
return JSValueIsBoolean(context(), m_value);
|
||||
}
|
||||
|
||||
bool asBoolean() const ALIGN_STACK {
|
||||
bool asBoolean() const {
|
||||
return JSValueToBoolean(context(), m_value);
|
||||
}
|
||||
|
||||
bool isNumber() const ALIGN_STACK {
|
||||
bool isNumber() const {
|
||||
return JSValueIsNumber(context(), m_value);
|
||||
}
|
||||
|
||||
bool isNull() const ALIGN_STACK {
|
||||
bool isNull() const {
|
||||
return JSValueIsNull(context(), m_value);
|
||||
}
|
||||
|
||||
bool isUndefined() const ALIGN_STACK {
|
||||
bool isUndefined() const {
|
||||
return JSValueIsUndefined(context(), m_value);
|
||||
}
|
||||
|
||||
double asNumber() const ALIGN_STACK {
|
||||
double asNumber() const {
|
||||
if (isNumber()) {
|
||||
return JSValueToNumber(context(), m_value, nullptr);
|
||||
} else {
|
||||
|
@ -204,22 +202,22 @@ public:
|
|||
return static_cast<uint32_t>(asNumber());
|
||||
}
|
||||
|
||||
bool isObject() const ALIGN_STACK {
|
||||
bool isObject() const {
|
||||
return JSValueIsObject(context(), m_value);
|
||||
}
|
||||
|
||||
Object asObject() ALIGN_STACK;
|
||||
Object asObject();
|
||||
|
||||
bool isString() const ALIGN_STACK {
|
||||
bool isString() const {
|
||||
return JSValueIsString(context(), m_value);
|
||||
}
|
||||
|
||||
String toString() ALIGN_STACK {
|
||||
String toString() {
|
||||
return String::adopt(JSValueToStringCopy(context(), m_value, nullptr));
|
||||
}
|
||||
|
||||
std::string toJSONString(unsigned indent = 0) const ALIGN_STACK;
|
||||
static Value fromJSON(JSContextRef ctx, const String& json) ALIGN_STACK;
|
||||
std::string toJSONString(unsigned indent = 0) const;
|
||||
static Value fromJSON(JSContextRef ctx, const String& json);
|
||||
protected:
|
||||
JSContextRef context() const;
|
||||
JSContextRef m_context;
|
||||
|
|
Loading…
Reference in New Issue