Commits

Bart van Strien committed fb1bf6a

Catch errors in love.font.newRasterizer, add luax_pconvobj which pcalls, allowing love.graphics.newFont to clean up before re-erroring

  • Participants
  • Parent commits c2d2934

Comments (0)

Files changed (4)

src/common/runtime.cpp

 	return 0;
 }
 
+int luax_pconvobj(lua_State *L, int idx, const char *mod, const char *fn)
+{
+	// Convert string to a file.
+	luax_getfunction(L, mod, fn);
+	lua_pushvalue(L, idx); // The initial argument.
+	int ret = lua_pcall(L, 1, 1, 0); // Call the function, one arg, one return value.
+	if (ret == 0)
+		lua_replace(L, idx); // Replace the initial argument with the new object.
+	return ret;
+}
+
+int luax_pconvobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn)
+{
+	luax_getfunction(L, mod, fn);
+	for (int i = 0; i < n; i++)
+	{
+		lua_pushvalue(L, idxs[i]); // The arguments.
+	}
+	int ret = lua_pcall(L, n, 1, 0); // Call the function, n args, one return value.
+	if (ret == 0)
+		lua_replace(L, idxs[0]); // Replace the initial argument with the new object.
+	return ret;
+}
+
 int luax_strtofile(lua_State *L, int idx)
 {
 	return luax_convobj(L, idx, "filesystem", "newFile");

src/common/runtime.h

  **/
 int luax_convobj(lua_State *L, int idxs[], int n, const char *module, const char *function);
 
+// pcall versions of the above
+int luax_pconvobj(lua_State *L, int idx, const char *module, const char *function);
+int luax_pconvobj(lua_State *L, int idxs[], int n, const char *module, const char *function);
+
 /**
  * 'Insist' that a table 'k' exists in the table at idx. Insistence involves that the
  * table (k) is created if it does not exist in the table at idx. The table at idx must

src/modules/font/freetype/wrap_Font.cpp

 int w_newRasterizer(lua_State *L)
 {
 	Rasterizer *t = NULL;
-	if (luax_istype(L, 1, IMAGE_IMAGE_DATA_T))
+	try
 	{
-		love::image::ImageData *d = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
-		const char *g = luaL_checkstring(L, 2);
-		std::string glyphs(g);
-		t = instance->newRasterizer(d, glyphs);
+		if (luax_istype(L, 1, IMAGE_IMAGE_DATA_T))
+		{
+			love::image::ImageData *d = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
+			const char *g = luaL_checkstring(L, 2);
+			std::string glyphs(g);
+			t = instance->newRasterizer(d, glyphs);
+		}
+		else if (luax_istype(L, 1, DATA_T))
+		{
+			Data *d = luax_checkdata(L, 1);
+			int size = luaL_checkint(L, 2);
+			t = instance->newRasterizer(d, size);
+		}
 	}
-	else if (luax_istype(L, 1, DATA_T))
+	catch (love::Exception &e)
 	{
-		Data *d = luax_checkdata(L, 1);
-		int size = luaL_checkint(L, 2);
-		t = instance->newRasterizer(d, size);
+		return luaL_error(L, "%s", e.what());
 	}
 
 	luax_newtype(L, "Rasterizer", FONT_RASTERIZER_T, t);

src/modules/graphics/opengl/wrap_Graphics.cpp

 	if (luax_istype(L, 1, DATA_T))
 	{
 		int idxs[] = {1, 2};
-		luax_convobj(L, idxs, 2, "font", "newRasterizer");
+		int ret = luax_pconvobj(L, idxs, 2, "font", "newRasterizer");
+		if (ret != 0)
+		{
+			font_data->release();
+			return lua_error(L);
+		}
 	}
 
 	if (font_data)