LiteLoaderBDS-1.16.40/ScriptEngine/API/NativePointer.cpp
2022-09-21 19:47:03 +08:00

402 lines
12 KiB
C++

#include "APIHelp.h"
#include "NativeAPI.h"
#include "NativeStdString.h"
#include <Utils/TypeConversionHelper.hpp>
//////////////////// NativePointer ////////////////////
ClassDefine<NativePointer>
NativePointerBuilder =
defineClass<NativePointer>("NativePointer")
.constructor(nullptr)
.function("fromSymbol", &NativePointer::fromSymbol)
.function("fromAddress", &NativePointer::fromAddress)
.function("malloc",&NativePointer::mallocMem)
.function("free", &NativePointer::freeMem)
.instanceFunction("asRawAddress", &NativePointer::asRawAddress)
.instanceFunction("asHexAddress", &NativePointer::asHexAddress)
.instanceFunction("asRef", &NativePointer::asRef)
.instanceFunction("deRef", &NativePointer::deRef)
.instanceFunction("isNull", &NativePointer::isNull)
.instanceFunction("offset", &NativePointer::offset)
.instanceProperty("byte", &NativePointer::getMemByte, &NativePointer::setMemByte)
.instanceProperty("int8", &NativePointer::getChar, &NativePointer::setChar)
.instanceProperty("uint8", &NativePointer::getUchar, &NativePointer::setUchar)
.instanceProperty("int16", &NativePointer::getShort, &NativePointer::setShort)
.instanceProperty("uint16", &NativePointer::getUshort, &NativePointer::setUshort)
.instanceProperty("int32", &NativePointer::getInt, &NativePointer::setInt)
.instanceProperty("uint32", &NativePointer::getUint, &NativePointer::setUint)
.instanceProperty("long", &NativePointer::getLong, &NativePointer::setLong)
.instanceProperty("ulong", &NativePointer::getUlong, &NativePointer::setUlong)
.instanceProperty("int64", &NativePointer::getLonglong, &NativePointer::setLonglong)
.instanceProperty("uint64", &NativePointer::getUlonglong, &NativePointer::setUlonglong)
.instanceProperty("float", &NativePointer::getFloat, &NativePointer::setFloat)
.instanceProperty("double", &NativePointer::getDouble, &NativePointer::setDouble)
.instanceProperty("string", &NativePointer::getString, &NativePointer::setString)
.instanceProperty("bool", &NativePointer::getBool, &NativePointer::setBool)
.instanceFunction("asStdString", &NativePointer::asStdString)
.build();
NativePointer::NativePointer(void* p)
: ScriptClass(ScriptClass::ConstructFromCpp<NativePointer>{}) {
set(p);
}
Local<Value> NativePointer::fromAddress(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
if (args[0].isString() ){
stringstream ss;
ss << hex << args[0].asString().toString();
uintptr_t res;
ss >> res;
return newNativePointer((void*)res);
} else if (args[0].isNumber()) {
return newNativePointer((void*)args[0].asNumber().toInt64());
}
LOG_WRONG_ARG_TYPE();
return Local<Value>();
}
Local<Value> NativePointer::fromSymbol(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
return newNativePointer(dlsym_real(args[0].asString().toStringHolder().c_str()));
}
Local<Value> NativePointer::mallocMem(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
size_t size = args[0].asNumber().toInt64();
return newNativePointer(malloc(size));
}
// directly free memblock in c runtime
Local<Value> NativePointer::freeMem(const Arguments& args) {
void* memObj = nullptr;
CHECK_ARGS_COUNT(args, 1);
if (args[0].isObject()) {
memObj = NativePointer::extract(args[0]);
} else if (args[0].isNumber()) {
*((__int64*)&memObj) = args[0].asNumber().toInt64();
}
if (!memObj) {
throw std::runtime_error("free(nullptr)");
}
free(memObj);
return Local<Value>();
}
Local<Object> NativePointer::newNativePointer(void* ptr) {
auto out = new NativePointer(ptr);
return out->getScriptObject();
}
void* NativePointer::extract(Local<Value> v) {
if (EngineScope::currentEngine()->isInstanceOf<NativePointer>(v))
return EngineScope::currentEngine()->getNativeInstance<NativePointer>(v)->get();
else
return nullptr;
}
Local<Value> NativePointer::asRawAddress(const Arguments& args) {
try {
void* pkt = unwrap();
if (!pkt)
return Local<Value>();
return Number::newNumber((intptr_t)pkt);
}
CATCH("Fail in NativePointer::asPointer!")
}
Local<Value> NativePointer::asHexAddress(const Arguments& args) {
try {
void* pkt = unwrap();
if (!pkt)
return Local<Value>();
std::stringstream ss;
ss << std::hex << (intptr_t)pkt;
return String::newString(ss.str());
}
CATCH("Fail in NativePointer::asHexStr!")
}
Local<Value> NativePointer::asRef(const Arguments& args) {
try {
return newNativePointer((void*)&mPtr);
}
CATCH("Fail in NativePointer::asRef!")
}
Local<Value> NativePointer::deRef(const Arguments& args) {
try {
return newNativePointer(*(void**)mPtr);
}
CATCH("Fail in NativePointer::deRef!")
}
Local<Value> NativePointer::isNull(const Arguments& args) {
try {
return script::Boolean::newBoolean(mPtr == nullptr);
}
CATCH("Fail in NativePointer::isNull!")
}
Local<Value> NativePointer::offset(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
auto ptr = get();
if (!ptr)
return Local<Value>();
return newNativePointer((void*)((uintptr_t)ptr + args[0].asNumber().toInt32()));
}
CATCH("Fail in NativePointer::offset!")
}
Local<Value> NativePointer::getMemByte() {
try {
auto ptr = get();
if (!ptr)
return Local<Value>();
std::vector<uint8_t> buffer(1);
ModUtils::MemCopy((uintptr_t)&buffer[0], (uintptr_t)ptr, buffer.size());
uint8_t em = buffer[0];
stringstream ss;
ss << hex << int(em);
return String::newString(ss.str());
}
CATCH("Fail in NativePointer::getMemByte!")
}
void NativePointer::setMemByte(const Local<Value>& value) {
try {
ModUtils::MemSet((uintptr_t)get(), (unsigned char)stoul(value.asString().toString(), nullptr, 16), 1);
} catch (...) {
logger.error("Fail to set mem!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getChar() {
try {
return Number::newNumber(*(char*)get());
}
CATCH("Fail in NativePointer::getChar!")
}
void NativePointer::setChar(const Local<Value>& value) {
try {
*(char*)get() = (char)value.asNumber().toInt32();
} catch (...) {
logger.error("Fail to set char!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getUchar() {
try {
return Number::newNumber(*(unsigned char*)get());
}
CATCH("Fail in NativePointer::getUchar!")
}
void NativePointer::setUchar(const Local<Value>& value) {
try {
*(unsigned char*)get() = (unsigned char)value.asNumber().toInt32();
} catch (...) {
logger.error("Fail to set uchar!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getShort() {
try {
return Number::newNumber(*(short*)get());
}
CATCH("Fail in NativePointer::getShort!")
}
void NativePointer::setShort(const Local<Value>& value) {
try {
*(short*)get() = (short)value.asNumber().toInt32();
} catch (...) {
logger.error("Fail to set short!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getUshort() {
try {
return Number::newNumber(*(unsigned short*)get());
}
CATCH("Fail in NativePointer::getUshort!")
}
void NativePointer::setUshort(const Local<Value>& value) {
try {
*(unsigned short*)get() = (unsigned short)value.asNumber().toInt32();
} catch (...) {
logger.error("Fail to set ushort!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getInt() {
try {
return Number::newNumber(*(int*)get());
}
CATCH("Fail in NativePointer::getInt!")
}
void NativePointer::setInt(const Local<Value>& value) {
try {
*(int*)get() = (int)value.asNumber().toInt32();
} catch (...) {
logger.error("Fail to set int!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getUint() {
try {
return Number::newNumber(*(long long*)get());
}
CATCH("Fail in NativePointer::getUint!")
}
void NativePointer::setUint(const Local<Value>& value) {
try {
*(unsigned int*)get() = (unsigned int)value.asNumber().toInt64();
} catch (...) {
logger.error("Fail to set uint!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getLong() {
try {
return Number::newNumber(*(long long*)get());
}
CATCH("Fail in NativePointer::getLong!")
}
void NativePointer::setLong(const Local<Value>& value) {
try {
*(long*)get() = (long)value.asNumber().toInt64();
} catch (...) {
logger.error("Fail to set long!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getUlong() {
try {
return Number::newNumber(*(long long*)get());
}
CATCH("Fail in NativePointer::getUlong!")
}
void NativePointer::setUlong(const Local<Value>& value) {
try {
*(unsigned long*)get() = (unsigned long)value.asNumber().toInt64();
} catch (...) {
logger.error("Fail to set ulong!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getLonglong() {
try {
return Number::newNumber(*(long long*)get());
}
CATCH("Fail in NativePointer::getLonglong!")
}
void NativePointer::setLonglong(const Local<Value>& value) {
try {
*(long long*)get() = (long long)value.asNumber().toInt64();
} catch (...) {
logger.error("Fail to set longlong!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getUlonglong() {
try {
return Number::newNumber(*(long long*)get());
}
CATCH("Fail in NativePointer::getUlonglong!")
}
void NativePointer::setUlonglong(const Local<Value>& value) {
try {
*(unsigned long long*)get() = (unsigned long long)value.asNumber().toInt64();
} catch (...) {
logger.error("Fail to set ulonglong!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getFloat() {
try {
return Number::newNumber(*(float*)get());
}
CATCH("Fail in NativePointer::getFloat!")
}
void NativePointer::setFloat(const Local<Value>& value) {
try {
*(float*)get() = (float)value.asNumber().toFloat();
} catch (...) {
logger.error("Fail to set float!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getDouble() {
try {
return Number::newNumber(*(double*)get());
}
CATCH("Fail in NativePointer::getDouble!")
}
void NativePointer::setDouble(const Local<Value>& value) {
try {
*(double*)get() = (double)value.asNumber().toFloat();
} catch (...) {
logger.error("Fail to set double!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getString() {
try {
return String::newString(*(string*)get());
}
CATCH("Fail in NativePointer::getString!")
}
void NativePointer::setString(const Local<Value>& value) {
try {
*(string*)get() = value.asString().toString();
} catch (...) {
logger.error("Fail to set string!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::getBool() {
try {
return Boolean::newBoolean(*(bool*)get());
}
CATCH("Fail in NativePointer::getBool!")
}
void NativePointer::setBool(const Local<Value>& value) {
try {
*(bool*)get() = value.asBoolean().value();
} catch (...) {
logger.error("Fail to set bool!");
logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName);
}
}
Local<Value> NativePointer::asStdString() {
try {
return NativeStdString::newNativeStdString((std::string*)mPtr);
}
CATCH("Fail in NativePointer::asStdString!")
}