/* * Tencent is pleased to support the open source community by making ScriptX available. * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. * * 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. */ #include #include "LuaHelper.hpp" namespace script { Local Object::newObject() { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_newtable(lua); return Local{lua_gettop(lua)}; } Local Object::newObjectImpl(const Local& type, size_t size, const Local* args) { return lua_backend::luaNewObject(type, size, args); } Local String::newString(const char* utf8) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_pushstring(lua, utf8); return Local(lua_gettop(lua)); } Local String::newString(std::string_view utf8) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_pushlstring(lua, utf8.data(), utf8.size()); return Local(lua_gettop(lua)); } Local String::newString(const std::string& utf8) { return newString(std::string_view(utf8)); } #if defined(__cpp_char8_t) Local String::newString(const char8_t* utf8) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_pushstring(lua, reinterpret_cast(utf8)); return Local(lua_gettop(lua)); } Local String::newString(std::u8string_view utf8) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_pushlstring(lua, reinterpret_cast(utf8.data()), utf8.size()); return Local(lua_gettop(lua)); } Local String::newString(const std::u8string& utf8) { return newString(std::u8string_view(utf8)); } #endif Local Number::newNumber(float value) { return newNumber(static_cast(value)); } Local Number::newNumber(double value) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_pushnumber(lua, value); return Local(lua_gettop(lua)); } Local Number::newNumber(int32_t value) { return newNumber(static_cast(value)); } Local Number::newNumber(int64_t value) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_pushinteger(lua, value); return Local(lua_gettop(lua)); } Local Boolean::newBoolean(bool value) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_pushboolean(lua, value); return Local(lua_gettop(lua)); } Local Function::newFunction(FunctionCallback callback) { auto engine = lua_backend::currentEngine(); auto lua = engine->lua_; lua_backend::luaEnsureStack(lua, 2); using ContextData = std::pair; auto context = std::make_unique(std::move(callback), engine); lua_backend::pushFinalizableUserData(lua, context.get(), [](void* data) { delete static_cast(data); }); lua_pushcclosure( lua, [](lua_State* lua) -> int { auto data = static_cast( lua_backend::getUserDataFromFinalizableUserData(lua, lua_upvalueindex(1))); auto& func = data->first; auto engine = data->second; auto paramCount = static_cast(lua_gettop(lua)); std::optional exception; try { Tracer trace(engine, "nativeFunction"); auto ret = func(lua_backend::LuaEngine::makeArguments(engine, 1, paramCount, false)); if (lua_backend::LuaEngine::localRefIndex(ret) == 0) { // no return value return 0; } else { lua_backend::pushValue(lua, ret); } return 1; } catch (const Exception& e) { exception = e.message(); } lua_backend::luaThrow(lua, exception); return 0; }, 1); context.release(); // NOLINT return Local{lua_gettop(lua)}; } Local Array::newArray(size_t size) { auto lua = lua_backend::currentLua(); lua_backend::luaEnsureStack(lua, 1); lua_createtable(lua, static_cast(size), 0); Local ret{lua_gettop(lua)}; return ret; } Local Array::newArrayImpl(size_t size, const Local* args) { auto ret = newArray(size); for (size_t i = 0; i < size; ++i) { ret.add(args[i]); } return ret; } Local ByteBuffer::newByteBuffer(size_t size) { try { return newByteBuffer( std::shared_ptr(new uint8_t[size], [](void* ptr) { delete[] static_cast(ptr); // NOLINT xxxxxxxxxx }), size); } catch (const std::bad_alloc&) { throw Exception("ByteBuffer create failed, OutOfMemory!!!"); } } Local ByteBuffer::newByteBuffer(void* nativeBuffer, size_t size) { auto ret = newByteBuffer(size); std::memcpy(ret.getRawBytes(), nativeBuffer, size); return ret; } Local ByteBuffer::newByteBuffer(std::shared_ptr nativeBuffer, size_t size) { StackFrameScope stack; auto engine = lua_backend::currentEngine(); auto ret = engine->byteBufferDelegate_->newByteBuffer(engine, std::move(nativeBuffer), size); return stack.returnValue(ret).asByteBuffer(); } } // namespace script