// push onto the Lua stack a userdata containing a pointer to T object static int push(lua_State *L, T *obj, bool gc=false) { if (!obj) { lua_pushnil(L); return 0; } luaL_getmetatable(L, ("Lunar_" + std::string(T::className)).c_str()); // lookup metatable in Lua registry if (lua_isnil(L, -1)) luaL_error(L, "%s missing metatable", T::className); int mt = lua_gettop(L); subtable(L, mt, "userdata", "v"); userdataType *ud = static_cast<userdataType*>(pushuserdata(L, obj, sizeof(userdataType))); if (ud) { ud->pT = obj; // store pointer to object in userdata lua_pushvalue(L, mt); lua_setmetatable(L, -2); if (gc == false) { lua_checkstack(L, 3); subtable(L, mt, "do not trash", "k"); lua_pushvalue(L, -2); lua_pushboolean(L, 1); lua_settable(L, -3); lua_pop(L, 1); } } lua_replace(L, mt); lua_settop(L, mt); return mt; // index of userdata containing pointer to T object }
static typename lutok::LObject<T>::Index lutok::LObject<T>::push(state& s, T* instance, bool gc) { if (!instance) { s.push_nil(); return 0; } luaL_getmetatable(s._pimpl->lua_state, T::s_lunaClassName); if (s.is_nil()) { luaL_error(s._pimpl->lua_state, "[Luna::%s] Class %s has not been commited!", __func__, T::s_lunaClassName); return 0; } lutok::LObject<T>::Index metatable = s.get_top(); subtable(s, metatable, "userdata", "v"); lutok::LObject<T>::Userdata * userdata = allocUserdata(s, metatable, instance); if (userdata) { userdata->pT = instance; s.push_value(metatable); s.set_metatable(); if (!gc) { lua_checkstack(s._pimpl->lua_state, 3); subtable(s, metatable, "unmanaged", "k"); s.push_value(-2); s.push_boolean(1); s.set_table(); s.pop(1); } } lua_replace(s._pimpl->lua_state, metatable); lua_settop(s._pimpl->lua_state, metatable); return metatable; }
U_NAMESPACE_BEGIN // read a 32-bit value that might only be 16-bit-aligned in memory #define READ_LONG(code) (le_uint32)((SWAPW(*(le_uint16*)&code) << 16) + SWAPW(*(((le_uint16*)&code) + 1))) // FIXME: should look at the format too... maybe have a sub-class for it? le_uint32 ExtensionSubtable::process(const LEReferenceTo<ExtensionSubtable> &thisRef, const LookupProcessor *lookupProcessor, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { if (LE_FAILURE(success)) { return 0; } le_uint16 elt = SWAPW(extensionLookupType); if (elt != lookupType) { le_uint32 extOffset = READ_LONG(extensionOffset); LEReferenceTo<LookupSubtable> subtable(thisRef, success, extOffset); if(LE_SUCCESS(success)) { return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success); } } return 0; }
void PushData(bool consume = false, data::File::Writer* pwriter = nullptr) { assert(!pwriter || consume); if (cache_) { // previous PushData() has stored data in cache_ data::File::Reader reader = cache_->GetReader(consume); while (reader.HasNext()) emitter_.Emit(reader.Next<TableItem>()); return; } if (!consume) { if (subranges_.empty()) { Flush(); } else { data::FilePtr cache = ctx_.GetFilePtr(dia_id_); data::File::Writer writer = cache_->GetWriter(); PushData(true, &writer); cache_ = cache; writer.Close(); } return; } // close File writers for (auto& w : subrange_writers_) { w.Close(); } if (pwriter) { FlushAndConsume<true>(pwriter); } else { FlushAndConsume(); } for (size_t i = 0; i < subranges_.size(); ++i) { ReduceByIndexPostPhase<TableItem, Key, Value, KeyExtractor, ReduceFunction, Emitter, VolatileKey, ReduceConfig> subtable(ctx_, dia_id_, key_extractor_, reduce_function_, emitter_.emit_, config_, neutral_element_); subtable.SetRange(subranges_[i]); subtable.Initialize(limit_memory_bytes_); { // insert items auto reader = subrange_files_[i]->GetConsumeReader(); while (reader.HasNext()) { subtable.Insert(reader.template Next<TableItem>()); } } subtable.PushData(consume || pwriter, pwriter); // delete File subrange_files_[i].reset(); } }
static void Register(lua_State *L) { luaL_checktype(L, -1, LUA_TTABLE); int module = lua_gettop(L); lua_newtable(L); // [-0,+1,e] int methods = lua_gettop(L); luaL_newmetatable(L, T::className); // [-0,+1,e] int metatable = lua_gettop(L); // store method table in module so that // scripts can add functions written in Lua. lua_pushvalue(L, methods); // [-0,+1,-] rawsetfield(L, module, T::className); // [-1,+0,e] lua_pushstring(L, T::className); // [-0,+1,-] rawsetfield(L, metatable, LUAX_STR_TYPENAME); // [-1,+0,e] // hide metatable from Lua getmetatable() lua_pushvalue(L, methods); // [-0,+1,-] rawsetfield(L, metatable, "_methodtable"); // [-1,+0,e] lua_pushvalue(L, methods); // [-0,+1,-] rawsetfield(L, metatable, "__index"); // [-1,+0,e] lua_pushcfunction(L, newindex_T); // [-0,+1,-] rawsetfield(L, metatable, "__newindex"); // [-1,+0,e] lua_pushcfunction(L, tostring_T); // [-0,+1,-] rawsetfield(L, metatable, "__tostring"); // [-1,+0,e] lua_pushcfunction(L, gc_T); // [-0,+1,-] rawsetfield(L, metatable, "__gc"); // [-1,+0,e] lua_newtable(L); // $mt (metatable of method table) // [-0,+1,e] lua_pushvalue(L, methods); // [-0,+1,-] lua_pushcclosure(L, new_T, 1); // [-1,+1,e] lua_pushvalue(L, -1); // dup new_T function // [-0,+1,-] rawsetfield(L, methods, "new"); // add new_T to method table // [-1,+0,e] rawsetfield(L, -2, "__call"); // $mt.__call = new_T // [-1,+0,e] lua_setmetatable(L, methods); // [-1,+0,-] // fill method table with methods from class T for (const typename LunarType<T>::Reg *l = T::methods; l->name; l++) { lua_pushlightuserdata(L, (void*)l); // [-0,+1,e] lua_pushcclosure(L, thunk, 1); // [-1,+1,e] if (strncmp(l->name, "__", 2) == 0) { rawsetfield(L, metatable, l->name); // [-1,+0,e] } else { rawsetfield(L, methods, l->name); // [-1,+0,e] } } subtable(L, metatable, "userdata", "v"); // mt.userdata = {} lua_settop(L, module); // drop locals }
le_uint32 ContextualSubstitutionSubtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { if (LE_FAILURE(success)) { return 0; } switch(SWAPW(subtableFormat)) { case 0: return 0; case 1: { LEReferenceTo<ContextualSubstitutionFormat1Subtable> subtable(base, success, (const ContextualSubstitutionFormat1Subtable *) this); if( LE_FAILURE(success) ) { return 0; } return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success); } case 2: { LEReferenceTo<ContextualSubstitutionFormat2Subtable> subtable(base, success, (const ContextualSubstitutionFormat2Subtable *) this); if( LE_FAILURE(success) ) { return 0; } return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success); } case 3: { LEReferenceTo<ContextualSubstitutionFormat3Subtable> subtable(base, success, (const ContextualSubstitutionFormat3Subtable *) this); if( LE_FAILURE(success) ) { return 0; } return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success); } default: return 0; } }
/** * Returns the value at the specified key. * @param keyName the key * @return the value */ Sendable *SmartDashboard::GetData(llvm::StringRef key) { std::shared_ptr<ITable> subtable(m_table->GetSubTable(key)); Sendable *data = m_tablesToData[subtable]; if (data == nullptr) { wpi_setGlobalWPIErrorWithContext(SmartDashboardMissingKey, key); return nullptr; } return data; }
// push onto the Lua stack a userdata containing a pointer to T object static int push(lua_State *L, T *obj, bool gc = false) { if (obj == nullptr) { return 0; } luaL_getmetatable(L, T::className); // [-0,+1,-] if (lua_isnil(L, -1)) { return luaL_error(L, "'%s' missing metatable", T::className); } int l_mt = lua_gettop(L); /* Was this pointer pushed already? Then pushuserdata pushed the existing copy */ if (!pushuserdata(L, obj)) { return 1; } int l_ud = lua_gettop(L); lua_pushvalue(L, l_mt); // dup(mt) lua_setmetatable(L, l_ud); // mt(ud)=mt [-1,+0,-] if (!gc) { subtable(L, l_mt, "do not trash", "k"); lua_pushvalue(L, l_ud); lua_pushboolean(L, true); lua_rawset(L, -3); } lua_settop(L, l_ud); lua_replace(L, l_mt); int nresult = LunarWrapper::prep(obj, L); if (nresult != 0) { const char *msg = nullptr; int err = lua_gettop(L); if (err >= 0) { msg = lua_tostring(L, err); } if (msg == nullptr) { msg = "(unknown error)"; } return luaL_error(L, "'%s' failed to prepare: %s", T::className, msg); } return 1; }
// FIXME: should look at the format too... maybe have a sub-class for it? le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { const LEReferenceTo<ExtensionSubtable> thisRef(lookupProcessor->getReference(), success); // create a reference to this if (LE_FAILURE(success)) { return 0; } le_uint16 elt = SWAPW(extensionLookupType); if (elt != lookupType) { le_uint32 extOffset = READ_LONG(extensionOffset); LEReferenceTo<LookupSubtable> subtable(thisRef, success, extOffset); if(LE_SUCCESS(success)) { return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success); } } return 0; }
le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { if (LE_FAILURE(success)) { return 0; } le_uint32 delta = 0; switch(lookupType) { case 0: break; case gpstSingle: { LEReferenceTo<SinglePositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstPair: { LEReferenceTo<PairPositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstCursive: { LEReferenceTo<CursiveAttachmentSubtable> subtable(lookupSubtable, success); delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstMarkToBase: { LEReferenceTo<MarkToBasePositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstMarkToLigature: { LEReferenceTo<MarkToLigaturePositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstMarkToMark: { LEReferenceTo<MarkToMarkPositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstContext: { LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, glyphIterator, fontInstance, success); break; } case gpstChainedContext: { LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, glyphIterator, fontInstance, success); break; } case gpstExtension: { LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, subtable, lookupType, glyphIterator, fontInstance, success); // Google patch: add subtable break; } default: break; } return delta; }