Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interface conversion error when trying to PullTable #27

Open
jtarchie opened this issue Mar 7, 2019 · 3 comments
Open

interface conversion error when trying to PullTable #27

jtarchie opened this issue Mar 7, 2019 · 3 comments

Comments

@jtarchie
Copy link

jtarchie commented Mar 7, 2019

To start off, I know I am doing something wrong. My usage of PullTable is based off the work done with encoding JSON support.

The value PullTable is trying to get would be the last return in the execution of the script.

When I try, I get the following error:

panic: interface conversion: lua.value is nil, not *lua.luaClosure

goroutine 1 [running]:
github.com/Shopify/go-lua.(*State).prototype(...)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/debug.go:14
github.com/Shopify/go-lua.(*State).currentLine(...)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/debug.go:17
github.com/Shopify/go-lua.(*State).runtimeError(0xc0000d8000, 0x116fafe, 0x15)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/debug.go:43 +0x2bc
github.com/Shopify/go-lua.(*State).next(0xc0000d8000, 0xc0000a23c0, 0x4, 0xc0000e2360)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/tables.go:230 +0x6eb
github.com/Shopify/go-lua.(*State).Next(0xc0000d8000, 0x3, 0x12821b1)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/lua.go:1193 +0x81
github.com/Shopify/goluago/util.pullTableRec(0xc0000d8000, 0xffffffffffffffff, 0x5, 0xc00009e320, 0xf, 0xc000094500)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/util/deep_pull.go:63 +0x11d
github.com/Shopify/goluago/util.toGoValue(0xc0000d8000, 0xffffffffffffffff, 0xc00009e320, 0xf, 0x10cdb01, 0xc0000d8000)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/util/deep_pull.go:143 +0x246
github.com/Shopify/goluago/util.pullTableRec(0xc0000d8000, 0x1, 0x5, 0xc0000d8000, 0x1, 0xffffffffffffffff)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/util/deep_pull.go:72 +0x17b
github.com/Shopify/goluago/util.PullTable(0xc0000d8000, 0x1, 0x5, 0x0, 0x0, 0xc00009e258)
        /Users/pivotal/go/pkg/mod/github.com/!shopify/[email protected]/util/deep_pull.go:47 +0x1ef
main.main()

The source to reproduce this problem:

package main

import (
	"github.com/Shopify/go-lua"
	"github.com/Shopify/goluago/util"
	"log"
	"os"
)

func main() {
	l := lua.NewState()
	source := `
local my_map = {
    key1="value1",
    key2="value2",
}
local some_list = {my_map, "item2"}
return({list_with_a_map=some_list})
`

	if err := lua.DoString(l, source); err != nil {
		panic(err)
	}

	index := 1
	if !l.IsTable(index) {
		log.Println("the last return value of the script must be a table")
		os.Exit(1)
	}

	_, err := util.PullTable(l, index)
	if err != nil {
		log.Panicln("getting table: %s", err)
	}
}

Any insight to what I am doing wrong?

@jtarchie
Copy link
Author

jtarchie commented Mar 7, 2019

After looking at the tests, I noticed that array is defined.
It appears that util.Open has to be used to have the array method available.

The updated code reflects this change and grabs the table.

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/Shopify/go-lua"
	"github.com/Shopify/goluago/util"
	"gopkg.in/yaml.v2"
)

func main() {
	l := lua.NewState()
	util.Open(l)

	source := `
local my_map = {
    key1="value1",
    key2="value2",
}
local some_list = array({my_map, "item2"})
return({list_with_a_map=some_list})
`

	if err := lua.DoString(l, source); err != nil {
		panic(err)
	}

	index := 1
	if !l.IsTable(index) {
		log.Println("the last return value of the script must be a table")
		os.Exit(1)
	}

	table, err := util.PullTable(l, index)
	if err != nil {
		log.Panicln("getting table: %s", err)
	}
	payload, err := yaml.Marshal(table)
	if err != nil {
		log.Panicln("marshaling yaml: %s", err)
	}
	fmt.Println(string(payload))
}

Why is the artifact array needed for determining if the lua table is an array rather than hash? This appears to have been created because the lua.table struct has no way of inspecting it for this meta information.

@jtarchie
Copy link
Author

jtarchie commented Mar 7, 2019

There's no good way to distinguishing via golang that a table is an array or hash.

With the following lua code, I believe there is a cheat, though maybe expensive.

function _.isArray(value)
  return type(value) == "table" and (value[1] or next(value) == nil)
end

This is taken from some of my old lua library.

If we can write the equivalent as a golang set of instructions. The use of array might not be needed.

I'm going to give it a try.

@jtarchie
Copy link
Author

jtarchie commented Mar 7, 2019

Using lua2c. I was able to get the following code generated.

 /* return type(value) == "table" and (value[1] or next(value) == nil) */
  lua_getfield(L,LUA_ENVIRONINDEX,"type");
  lua_getfield(L,LUA_ENVIRONINDEX,"value");
  lua_call(L,1,1);
  lua_pushliteral(L,"table");
  const int lc1 = lua_equal(L,-2,-1);
  lua_pop(L,2);
  lua_pushboolean(L,lc1);
  if (lua_toboolean(L,-1)) {
    lua_pop(L,1);
    lua_getfield(L,LUA_ENVIRONINDEX,"value");
    lua_pushnumber(L,1);
    lua_gettable(L,-2);
    lua_remove(L,-2);
    if (!(lua_toboolean(L,-1))) {
      lua_pop(L,1);
      lua_getfield(L,LUA_ENVIRONINDEX,"next");
      lua_getfield(L,LUA_ENVIRONINDEX,"value");
      lua_call(L,1,1);
      lua_pushnil(L);
      const int lc2 = lua_equal(L,-2,-1);
      lua_pop(L,2);
      lua_pushboolean(L,lc2);
    }
  }

I'll just see if this can be converted to the equivalent golang code.

Update: I think I found the equivalant commands. Don't think I'm going to get this done tonight, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant