blob: ce441929841cb3ab2bf59d151739e7285ecbeade [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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 "utils/lua-utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "lauxlib.h"
#include "lualib.h"
#ifdef __cplusplus
}
#endif
namespace libtextclassifier3 {
namespace {
static const int kEnvIndex = 1;
static const int kCallbackIdIndex = 2;
static const luaL_Reg defaultlibs[] = {{"_G", luaopen_base},
{LUA_TABLIBNAME, luaopen_table},
{LUA_STRLIBNAME, luaopen_string},
{LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
{nullptr, nullptr}};
} // namespace
void LuaEnvironment::LoadDefaultLibraries() {
for (const luaL_Reg *lib = defaultlibs; lib->func; lib++) {
luaL_requiref(state_, lib->name, lib->func, 1);
lua_pop(state_, 1); /* remove lib */
}
}
int LuaEnvironment::CallbackDispatch(lua_State *state) {
// Fetch reference to our environment.
LuaEnvironment *env = static_cast<LuaEnvironment *>(
lua_touserdata(state, lua_upvalueindex(kEnvIndex)));
TC3_CHECK_EQ(env->state_, state);
int callback_id = lua_tointeger(state, lua_upvalueindex(kCallbackIdIndex));
return env->HandleCallback(callback_id);
}
LuaEnvironment::LuaEnvironment() { state_ = luaL_newstate(); }
LuaEnvironment::~LuaEnvironment() {
if (state_ != nullptr) {
lua_close(state_);
}
}
void LuaEnvironment::PushCallback(int callback_id) {
lua_pushlightuserdata(state_, static_cast<void *>(this));
lua_pushnumber(state_, callback_id);
lua_pushcclosure(state_, CallbackDispatch, 2);
}
void LuaEnvironment::SetupTableLookupCallback(const char *name,
int callback_id) {
lua_newtable(state_);
luaL_newmetatable(state_, name);
PushCallback(callback_id);
lua_setfield(state_, -2, "__index");
lua_setmetatable(state_, -2);
}
void LuaEnvironment::PushValue(const Variant &value) {
if (value.HasInt()) {
lua_pushnumber(state_, value.IntValue());
} else if (value.HasInt64()) {
lua_pushnumber(state_, value.Int64Value());
} else if (value.HasBool()) {
lua_pushboolean(state_, value.BoolValue());
} else if (value.HasFloat()) {
lua_pushnumber(state_, value.FloatValue());
} else if (value.HasDouble()) {
lua_pushnumber(state_, value.DoubleValue());
} else if (value.HasString()) {
lua_pushstring(state_, value.StringValue().data());
} else {
TC3_LOG(FATAL) << "Unknown value type.";
}
}
int LuaEnvironment::HandleCallback(int callback_id) { return LUA_ERRRUN; }
} // namespace libtextclassifier3