Esempio n. 1
0
 // 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
 }
Esempio n. 2
0
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;
}