case UC_ARRAY:
case UC_OBJECT:
- if (!visited) {
- freetbl = true;
- visited = lh_kptr_table_new(16, NULL);
+ if (ucv_prototype_get(uv)) {
+ ud = lua_newuserdata(L, sizeof(*ud));
+
+ if (ud) {
+ ud->vm = vm;
+ ud->uv = ucv_get(uv);
+
+ luaL_getmetatable(L, "ucode.value");
+ lua_setmetatable(L, -2);
+ }
+ else {
+ lua_pushnil(L);
+ }
}
+ else {
+ if (!visited) {
+ freetbl = true;
+ visited = lh_kptr_table_new(16, NULL);
+ }
- if (visited) {
- if (lua_table_new_or_ref(L, visited, uv)) {
- if (ucv_type(uv) == UC_ARRAY) {
- for (i = 0; i < ucv_array_length(uv); i++) {
- e = ucv_array_get(uv, i);
- ucv_to_lua(vm, e, L, visited);
- lua_rawseti(L, -2, (int)i + 1);
+ if (visited) {
+ if (lua_table_new_or_ref(L, visited, uv)) {
+ if (ucv_type(uv) == UC_ARRAY) {
+ for (i = 0; i < ucv_array_length(uv); i++) {
+ e = ucv_array_get(uv, i);
+ ucv_to_lua(vm, e, L, visited);
+ lua_rawseti(L, -2, (int)i + 1);
+ }
}
- }
- else {
- ucv_object_foreach(uv, key, val) {
- ucv_to_lua(vm, val, L, visited);
- lua_setfield(L, -2, key);
+ else {
+ ucv_object_foreach(uv, key, val) {
+ ucv_to_lua(vm, val, L, visited);
+ lua_setfield(L, -2, key);
+ }
}
}
}
- }
- else {
- lua_pushnil(L);
+ else {
+ lua_pushnil(L);
+ }
}
break;
ucv_userdata_t *ud = luaL_checkudata(L, 1, "ucode.value");
int nargs = lua_gettop(L), i;
uc_value_t *rv;
+ lua_Debug ar;
+ bool mcall;
if (!ucv_is_callable(ud->uv))
return luaL_error(L, "%s: Invoked value is not a function",
uc_exception_type_name(EXCEPTION_TYPE));
+ if (!lua_getstack(L, 0, &ar) || !lua_getinfo(L, "n", &ar))
+ return luaL_error(L, "%s: Unable to obtain stackframe information",
+ uc_exception_type_name(EXCEPTION_RUNTIME));
+
+ mcall = !strcmp(ar.namewhat, "method");
+
+ if (mcall)
+ uc_vm_stack_push(ud->vm, lua_to_ucv(L, 2, ud->vm, NULL));
+
uc_vm_stack_push(ud->vm, ucv_get(ud->uv));
- for (i = 2; i <= nargs; i++)
+ for (i = 2 + mcall; i <= nargs; i++)
uc_vm_stack_push(ud->vm, lua_to_ucv(L, i, ud->vm, NULL));
- if (uc_vm_call(ud->vm, false, nargs - 1)) {
+ if (uc_vm_call(ud->vm, mcall, nargs - 1 - mcall)) {
rv = ucv_object_get(ucv_array_get(ud->vm->exception.stacktrace, 0), "context", NULL);
return luaL_error(L, "%s: %s%s%s",
return 1;
}
+static int
+lua_uv_index(lua_State *L)
+{
+ ucv_userdata_t *ud = luaL_checkudata(L, 1, "ucode.value");
+ const char *key = luaL_checkstring(L, 2);
+ uc_value_t *proto, *rv;
+ bool found;
+
+ proto = ucv_prototype_get(ud->uv);
+ rv = ucv_object_get(proto, key, &found);
+
+ if (!found)
+ return 0;
+
+ ucv_to_lua(ud->vm, rv, L, NULL);
+ ucv_put(rv);
+
+ return 1;
+}
+
static int
lua_uv_tostring(lua_State *L)
{
static const luaL_reg ucode_ud_methods[] = {
{ "__gc", lua_uv_gc },
{ "__call", lua_uv_call },
+ { "__index", lua_uv_index },
{ "__tostring", lua_uv_tostring },
{ }
luaL_newmetatable(L, "ucode.value");
luaL_register(L, NULL, ucode_ud_methods);
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "__index");
lua_pop(L, 1);
return uc_resource_new(vm_type, L);