xref: /netbsd-src/usr.sbin/acpitools/aml/aml_evalobj.c (revision 016d86ee89bb23b2f1eebdb90a9837da17f21554)
1*016d86eeSandvar /*	$NetBSD: aml_evalobj.c,v 1.4 2024/07/31 20:15:33 andvar Exp $	*/
253e202c1Schristos 
353e202c1Schristos /*-
453e202c1Schristos  * Copyright (c) 1999 Takanori Watanabe
553e202c1Schristos  * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
653e202c1Schristos  * All rights reserved.
753e202c1Schristos  *
853e202c1Schristos  * Redistribution and use in source and binary forms, with or without
953e202c1Schristos  * modification, are permitted provided that the following conditions
1053e202c1Schristos  * are met:
1153e202c1Schristos  * 1. Redistributions of source code must retain the above copyright
1253e202c1Schristos  *    notice, this list of conditions and the following disclaimer.
1353e202c1Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1453e202c1Schristos  *    notice, this list of conditions and the following disclaimer in the
1553e202c1Schristos  *    documentation and/or other materials provided with the distribution.
1653e202c1Schristos  *
1753e202c1Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1853e202c1Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1953e202c1Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2053e202c1Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2153e202c1Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2253e202c1Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2353e202c1Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2453e202c1Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2553e202c1Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2653e202c1Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2753e202c1Schristos  * SUCH DAMAGE.
2853e202c1Schristos  *
2953e202c1Schristos  *	Id: aml_evalobj.c,v 1.27 2000/08/16 18:14:53 iwasaki Exp
3053e202c1Schristos  *	$FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_evalobj.c,v 1.4 2000/11/09 06:24:45 iwasaki Exp $
3153e202c1Schristos  */
3253e202c1Schristos #include <sys/cdefs.h>
33*016d86eeSandvar __RCSID("$NetBSD: aml_evalobj.c,v 1.4 2024/07/31 20:15:33 andvar Exp $");
3453e202c1Schristos 
3553e202c1Schristos #include <sys/param.h>
3653e202c1Schristos 
3753e202c1Schristos #include <acpi_common.h>
3853e202c1Schristos #include <aml/aml_amlmem.h>
3953e202c1Schristos #include <aml/aml_common.h>
4053e202c1Schristos #include <aml/aml_env.h>
4153e202c1Schristos #include <aml/aml_evalobj.h>
4253e202c1Schristos #include <aml/aml_name.h>
4353e202c1Schristos #include <aml/aml_obj.h>
4453e202c1Schristos #include <aml/aml_parse.h>
4553e202c1Schristos #include <aml/aml_region.h>
4653e202c1Schristos #include <aml/aml_status.h>
4753e202c1Schristos #include <aml/aml_store.h>
4853e202c1Schristos 
4953e202c1Schristos #ifndef _KERNEL
5053e202c1Schristos #include <sys/param.h>
5153e202c1Schristos #include <sys/stat.h>
5253e202c1Schristos #include <sys/mman.h>
5353e202c1Schristos 
5453e202c1Schristos #include <assert.h>
5553e202c1Schristos #include <err.h>
5653e202c1Schristos #include <fcntl.h>
5753e202c1Schristos #include <stdio.h>
5853e202c1Schristos #include <stdlib.h>
5953e202c1Schristos #include <string.h>
6053e202c1Schristos 
6153e202c1Schristos #include "debug.h"
6253e202c1Schristos #else /* _KERNEL */
6353e202c1Schristos #include <sys/systm.h>
6453e202c1Schristos #endif /* !_KERNEL */
6553e202c1Schristos 
6653e202c1Schristos static union aml_object	*aml_eval_fieldobject(struct aml_environ *env,
6753e202c1Schristos 					      struct aml_name *name);
6853e202c1Schristos 
6953e202c1Schristos static union aml_object *
7053e202c1Schristos aml_eval_fieldobject(struct aml_environ *env, struct aml_name *name)
7153e202c1Schristos {
7253e202c1Schristos 	int	num;
7353e202c1Schristos 	struct	aml_name *oname,*wname;
7453e202c1Schristos 	struct	aml_field *field;
7553e202c1Schristos 	struct	aml_opregion *or;
7653e202c1Schristos 	union	aml_object tobj;
7753e202c1Schristos 
7853e202c1Schristos 	num = 0;
7953e202c1Schristos 	/* CANNOT OCCUR! */
8053e202c1Schristos 	if (name == NULL || name->property == NULL ||
8153e202c1Schristos 	    name->property->type != aml_t_field) {
8253e202c1Schristos 		printf("????\n");
8353e202c1Schristos 		env->stat = aml_stat_panic;
8453e202c1Schristos 		return (NULL);
8553e202c1Schristos 	}
8653e202c1Schristos 	field = &name->property->field;
8753e202c1Schristos 	oname = env->curname;
8853e202c1Schristos 	if (field->bitlen > 32) {
8953e202c1Schristos 		env->tempobject.type = aml_t_regfield;
9053e202c1Schristos 	} else {
9153e202c1Schristos 		env->tempobject.type = aml_t_num;
9253e202c1Schristos 	}
9353e202c1Schristos 	env->curname = name;
9453e202c1Schristos 	if (field->f.ftype == f_t_field) {
9553e202c1Schristos 		wname = aml_search_name(env, field->f.fld.regname);
9653e202c1Schristos 		if (wname == NULL || wname->property == NULL ||
9753e202c1Schristos 		    wname->property->type != aml_t_opregion) {
98*016d86eeSandvar 			AML_DEBUGPRINT("Inappropriate Type\n");
9953e202c1Schristos 			env->stat = aml_stat_panic;
10053e202c1Schristos 			env->curname = oname;
10153e202c1Schristos 			return (NULL);
10253e202c1Schristos 		}
10353e202c1Schristos 		or = &wname->property->opregion;
10453e202c1Schristos 		if (env->tempobject.type == aml_t_regfield) {
10553e202c1Schristos 			env->tempobject.regfield.space = or->space;
10653e202c1Schristos 			env->tempobject.regfield.flags = field->flags;
10753e202c1Schristos 			env->tempobject.regfield.offset = or->offset;
10853e202c1Schristos 			env->tempobject.regfield.bitoffset = field->bitoffset;
10953e202c1Schristos 			env->tempobject.regfield.bitlen = field->bitlen;
11053e202c1Schristos 		} else {
11153e202c1Schristos 			env->tempobject.type = aml_t_num;
11253e202c1Schristos 			env->tempobject.num.number = aml_region_read(env,
11353e202c1Schristos 			    or->space, field->flags, or->offset,
11453e202c1Schristos 			    field->bitoffset, field->bitlen);
11553e202c1Schristos 			AML_DEBUGPRINT("[read(%d, 0x%x)->0x%x]",
11653e202c1Schristos 			    or->space, or->offset + field->bitoffset / 8,
11753e202c1Schristos 			    env->tempobject.num.number);
11853e202c1Schristos 		}
11953e202c1Schristos 	} else if (field->f.ftype == f_t_index) {
12053e202c1Schristos 		wname = aml_search_name(env, field->f.ifld.indexname);
12153e202c1Schristos 		tobj.type = aml_t_num;
12253e202c1Schristos 		tobj.num.number = field->bitoffset / 8;/* AccessType Boundary */
12353e202c1Schristos 		aml_store_to_name(env, &tobj, wname);
12453e202c1Schristos 		wname = aml_search_name(env, field->f.ifld.dataname);
12553e202c1Schristos 		num = aml_objtonum(env, aml_eval_name(env, wname));
12653e202c1Schristos 		env->tempobject.type = aml_t_num;
12753e202c1Schristos 		env->tempobject.num.number = (num >> (field->bitoffset & 7)) &
12853e202c1Schristos 		    ((1 << field->bitlen) - 1);
12953e202c1Schristos 	}
13053e202c1Schristos 	env->curname = oname;
13153e202c1Schristos 	return (&env->tempobject);
13253e202c1Schristos }
13353e202c1Schristos 
13453e202c1Schristos union aml_object *
13553e202c1Schristos aml_eval_objref(struct aml_environ *env, union aml_object *obj)
13653e202c1Schristos {
13753e202c1Schristos 	int	offset;
13853e202c1Schristos 	union	aml_object num1;
13953e202c1Schristos 	union	aml_object *ref, *ret;
14053e202c1Schristos 
14153e202c1Schristos 	ret = obj;
14253e202c1Schristos 	if (obj->objref.deref == 1) {
14353e202c1Schristos 		num1.type = aml_t_num;
14453e202c1Schristos 		offset = obj->objref.offset;
14553e202c1Schristos 		ref = obj->objref.ref;
14653e202c1Schristos 		if (ref == NULL) {
14753e202c1Schristos 			goto out;
14853e202c1Schristos 		}
14953e202c1Schristos 		switch (ref->type) {
15053e202c1Schristos 		case aml_t_package:
15153e202c1Schristos 			if (ref->package.elements > offset) {
15253e202c1Schristos 				ret = ref->package.objects[offset];
15353e202c1Schristos 			} else {
15453e202c1Schristos 				num1.num.number = 0;
15553e202c1Schristos 				env->tempobject = num1;
15653e202c1Schristos 				ret = &env->tempobject;
15753e202c1Schristos 			}
15853e202c1Schristos 			break;
15953e202c1Schristos 		case aml_t_buffer:
16053e202c1Schristos 			if (ref->buffer.size > offset) {
16153e202c1Schristos 				num1.num.number = ref->buffer.data[offset] & 0xff;
16253e202c1Schristos 			} else {
16353e202c1Schristos 				num1.num.number = 0;
16453e202c1Schristos 			}
16553e202c1Schristos 			env->tempobject = num1;
16653e202c1Schristos 			ret = &env->tempobject;
16753e202c1Schristos 			break;
16853e202c1Schristos 		default:
16953e202c1Schristos 			break;
17053e202c1Schristos 		}
17153e202c1Schristos 	}
17253e202c1Schristos 	if (obj->objref.alias == 1) {
17353e202c1Schristos 		ret = aml_eval_name(env, obj->objref.nameref);
17453e202c1Schristos 		goto out;
17553e202c1Schristos 	}
17653e202c1Schristos out:
17753e202c1Schristos 	return (ret);
17853e202c1Schristos }
17953e202c1Schristos 
18053e202c1Schristos /*
18153e202c1Schristos  * Eval named object.
18253e202c1Schristos  */
18353e202c1Schristos union aml_object *
18453e202c1Schristos aml_eval_name(struct aml_environ *env, struct aml_name *aname)
18553e202c1Schristos {
18653e202c1Schristos 	int	argnum, i;
18753e202c1Schristos 	int	num;
18853e202c1Schristos 	struct	aml_name *tmp;
18953e202c1Schristos 	struct	aml_environ *copy;
19053e202c1Schristos 	struct	aml_local_stack *stack;
19153e202c1Schristos 	union	aml_object *obj, *ret;
19253e202c1Schristos 	union	aml_object *src;
19353e202c1Schristos 
19453e202c1Schristos 	ret = NULL;
19553e202c1Schristos 	if (aname == NULL || aname->property == NULL) {
19653e202c1Schristos 		return (NULL);
19753e202c1Schristos 	}
19853e202c1Schristos 	if (env->stat == aml_stat_panic) {
19953e202c1Schristos 		return (NULL);
20053e202c1Schristos 	}
20153e202c1Schristos 	copy = memman_alloc(aml_memman, memid_aml_environ);
20253e202c1Schristos 	if (copy == NULL) {
20353e202c1Schristos 		return (NULL);
20453e202c1Schristos 	}
20553e202c1Schristos 	ret = aname->property;
20653e202c1Schristos 	i = 0;
20753e202c1Schristos reevaluate:
20853e202c1Schristos 	if (i > 10) {
20953e202c1Schristos 		env->stat = aml_stat_panic;
21053e202c1Schristos 		printf("TOO MANY LOOP\n");
21153e202c1Schristos 		ret = NULL;
21253e202c1Schristos 		goto out;
21353e202c1Schristos 	}
21453e202c1Schristos 	switch (aname->property->type) {
21553e202c1Schristos 	case aml_t_namestr:
21653e202c1Schristos 		tmp = aname;
21753e202c1Schristos 		aname = aml_search_name(env, aname->property->nstr.dp);
21853e202c1Schristos 		if (aname == NULL) {
21953e202c1Schristos 			aname = tmp;
22053e202c1Schristos 		}
22153e202c1Schristos 		i++;
22253e202c1Schristos 		goto reevaluate;
22353e202c1Schristos 	case aml_t_objref:
22453e202c1Schristos 		ret = aml_eval_objref(env, aname->property);
22553e202c1Schristos 		goto out;
22653e202c1Schristos 	case aml_t_num:
22753e202c1Schristos 	case aml_t_string:
22853e202c1Schristos 	case aml_t_buffer:
22953e202c1Schristos 	case aml_t_package:
23053e202c1Schristos 	case aml_t_debug:
23153e202c1Schristos 		ret = aname->property;
23253e202c1Schristos 		goto out;
23353e202c1Schristos 	case aml_t_field:
23453e202c1Schristos 		aml_free_objectcontent(&env->tempobject);
23553e202c1Schristos 		ret = aml_eval_fieldobject(env, aname);
23653e202c1Schristos 		goto out;
23753e202c1Schristos 	case aml_t_method:
23853e202c1Schristos 		aml_free_objectcontent(&env->tempobject);
23953e202c1Schristos 		argnum = aname->property->meth.argnum & 7;
24053e202c1Schristos 		*copy = *env;
24153e202c1Schristos 		copy->curname = aname;
24253e202c1Schristos 		copy->dp = aname->property->meth.from;
24353e202c1Schristos 		copy->end = aname->property->meth.to;
24453e202c1Schristos 		copy->stat = aml_stat_none;
24553e202c1Schristos 		stack = aml_local_stack_create();
24653e202c1Schristos 		AML_DEBUGPRINT("(");
24753e202c1Schristos 		for (i = 0; i < argnum; i++) {
24853e202c1Schristos 			aml_local_stack_getArgX(stack, i)->property =
24953e202c1Schristos 			    aml_copy_object(env,
25053e202c1Schristos 				aml_eval_name(env,
25153e202c1Schristos 				    aml_parse_termobj(env, 0)));
25253e202c1Schristos 			if (i < argnum - 1)
25353e202c1Schristos 				AML_DEBUGPRINT(", ");
25453e202c1Schristos 		}
25553e202c1Schristos 		AML_DEBUGPRINT(")\n");
25653e202c1Schristos 		aml_local_stack_push(stack);
25753e202c1Schristos 		if (env->stat == aml_stat_step) {
25853e202c1Schristos 			AML_DEBUGGER(env, copy);
25953e202c1Schristos 		}
26053e202c1Schristos 		tmp = aml_execute_method(copy);
26153e202c1Schristos 		obj = aml_eval_name(env, tmp);
26253e202c1Schristos 		if (copy->stat == aml_stat_panic) {
2631a03346fSmsaitoh 			AML_DEBUGPRINT("PANIC OCCURRED IN METHOD");
26453e202c1Schristos 			env->stat = aml_stat_panic;
26553e202c1Schristos 			ret = NULL;
26653e202c1Schristos 			aml_local_stack_delete(aml_local_stack_pop());
26753e202c1Schristos 			goto out;
26853e202c1Schristos 		}
26953e202c1Schristos 		if (aml_debug) {
27053e202c1Schristos 			aml_showobject(obj);
27153e202c1Schristos 		}
27253e202c1Schristos 
27353e202c1Schristos 		if (tmp)
27453e202c1Schristos 			tmp->property = NULL;
27553e202c1Schristos 		aml_local_stack_delete(aml_local_stack_pop());
27653e202c1Schristos 		if (obj) {
27753e202c1Schristos 			aml_create_local_object()->property = obj;
27853e202c1Schristos 			ret = obj;
27953e202c1Schristos 		} else {
28053e202c1Schristos 			env->tempobject.type = aml_t_num;
28153e202c1Schristos 			env->tempobject.num.number = 0;
28253e202c1Schristos 		}
28353e202c1Schristos 
28453e202c1Schristos 		goto out;
28553e202c1Schristos 	case aml_t_bufferfield:
28653e202c1Schristos 		aml_free_objectcontent(&env->tempobject);
28753e202c1Schristos 		if (aname->property->bfld.bitlen > 32) {
28853e202c1Schristos 			ret = aname->property;
28953e202c1Schristos 		} else {
29053e202c1Schristos 			src = aname->property;
29153e202c1Schristos 			num = aml_bufferfield_read(src->bfld.origin,
29253e202c1Schristos 			    src->bfld.bitoffset, src->bfld.bitlen);
29353e202c1Schristos 			env->tempobject.type = aml_t_num;
29453e202c1Schristos 			env->tempobject.num.number = num;
29553e202c1Schristos 			ret = &env->tempobject;
29653e202c1Schristos 		}
29753e202c1Schristos 		goto out;
29853e202c1Schristos 	default:
29953e202c1Schristos 		AML_DEBUGPRINT("I eval the object that I should not eval, %s%d",
30053e202c1Schristos 		    aname->name, aname->property->type);
30153e202c1Schristos 		AML_SYSABORT();
30253e202c1Schristos 		ret = NULL;
30353e202c1Schristos 		goto out;
30453e202c1Schristos 	}
30553e202c1Schristos out:
30653e202c1Schristos 	memman_free(aml_memman, memid_aml_environ, copy);
30753e202c1Schristos 	return (ret);
30853e202c1Schristos }
30953e202c1Schristos 
31053e202c1Schristos /*
31153e202c1Schristos  * Eval named object but env variable is not required and return
31253e202c1Schristos  * status of evaluation (success is zero).  This function is assumed
31353e202c1Schristos  * to be called by aml_apply_foreach_found_objects().
31453e202c1Schristos  * Note that no arguments are passed if object is a method.
31553e202c1Schristos  */
31653e202c1Schristos 
31753e202c1Schristos int
31853e202c1Schristos aml_eval_name_simple(struct aml_name *name, va_list ap)
31953e202c1Schristos {
32053e202c1Schristos 	struct	aml_environ *env;
32153e202c1Schristos 	union	aml_object *ret;
32253e202c1Schristos 
32353e202c1Schristos 	if (name == NULL || name->property == NULL) {
32453e202c1Schristos 		return (1);
32553e202c1Schristos 	}
32653e202c1Schristos 
32753e202c1Schristos 	env = memman_alloc(aml_memman, memid_aml_environ);
32853e202c1Schristos 	if (env == NULL) {
32953e202c1Schristos 		return (1);
33053e202c1Schristos 	}
33153e202c1Schristos 	bzero(env, sizeof(struct aml_environ));
33253e202c1Schristos 
33353e202c1Schristos 	aml_local_stack_push(aml_local_stack_create());
33453e202c1Schristos 
33553e202c1Schristos 	AML_DEBUGPRINT("Evaluating ");
33653e202c1Schristos 	aml_print_curname(name);
33753e202c1Schristos 	ret = aml_eval_name(env, name);
33853e202c1Schristos 	if (name->property->type != aml_t_method) {
33953e202c1Schristos 		AML_DEBUGPRINT("\n");
34053e202c1Schristos 		if (aml_debug) {
34153e202c1Schristos 			aml_showobject(ret);
34253e202c1Schristos 		}
34353e202c1Schristos 	}
34453e202c1Schristos 
34553e202c1Schristos 	aml_local_stack_delete(aml_local_stack_pop());
34653e202c1Schristos 
34753e202c1Schristos 	memman_free(aml_memman, memid_aml_environ, env);
34853e202c1Schristos 	return (0);
34953e202c1Schristos }
35053e202c1Schristos 
35153e202c1Schristos int
35253e202c1Schristos aml_objtonum(struct aml_environ *env, union aml_object *obj)
35353e202c1Schristos {
35453e202c1Schristos 
35553e202c1Schristos 	if (obj != NULL && obj->type == aml_t_num) {
35653e202c1Schristos 		return (obj->num.number);
35753e202c1Schristos 	} else {
35853e202c1Schristos 		env->stat = aml_stat_panic;
35953e202c1Schristos 		return (-1);
36053e202c1Schristos 	}
36153e202c1Schristos }
36253e202c1Schristos 
36353e202c1Schristos struct aml_name *
36453e202c1Schristos aml_execute_method(struct aml_environ *env)
36553e202c1Schristos {
36653e202c1Schristos 	struct	aml_name *name;
36753e202c1Schristos 	struct	aml_name_group *newgrp;
36853e202c1Schristos 
3697ac7d15dSdogcow 	newgrp = aml_new_name_group((void *)AML_NAME_GROUP_IN_METHOD);
37053e202c1Schristos 
37153e202c1Schristos 	AML_DEBUGPRINT("[");
37253e202c1Schristos 	aml_print_curname(env->curname);
37353e202c1Schristos 	AML_DEBUGPRINT(" START]\n");
37453e202c1Schristos 
37553e202c1Schristos 	name = aml_parse_objectlist(env, 0);
37653e202c1Schristos 	AML_DEBUGPRINT("[");
37753e202c1Schristos 	aml_print_curname(env->curname);
37853e202c1Schristos 	AML_DEBUGPRINT(" END]\n");
37953e202c1Schristos 
38053e202c1Schristos 	aml_delete_name_group(newgrp);
38153e202c1Schristos 	return (name);
38253e202c1Schristos }
38353e202c1Schristos 
38453e202c1Schristos union aml_object *
38553e202c1Schristos aml_invoke_method(struct aml_name *name, int argc, union aml_object *argv)
38653e202c1Schristos {
38753e202c1Schristos 	int	i;
38853e202c1Schristos 	struct	aml_name *tmp;
38953e202c1Schristos 	struct	aml_environ *env;
39053e202c1Schristos 	struct	aml_local_stack *stack;
39153e202c1Schristos 	union	aml_object *retval;
39253e202c1Schristos 	union	aml_object *obj;
39353e202c1Schristos 
39453e202c1Schristos 	retval = NULL;
39553e202c1Schristos 	env = memman_alloc(aml_memman, memid_aml_environ);
39653e202c1Schristos 	if (env == NULL) {
39753e202c1Schristos 		return (NULL);
39853e202c1Schristos 	}
39953e202c1Schristos 	bzero(env, sizeof(struct aml_environ));
40053e202c1Schristos 
40153e202c1Schristos 	if (name != NULL && name->property != NULL &&
40253e202c1Schristos 	    name->property->type == aml_t_method) {
40353e202c1Schristos 		env->curname = name;
40453e202c1Schristos 		env->dp = name->property->meth.from;
40553e202c1Schristos 		env->end = name->property->meth.to;
40653e202c1Schristos 		AML_DEBUGGER(env, env);
40753e202c1Schristos 		stack = aml_local_stack_create();
40853e202c1Schristos 		for (i = 0; i < argc; i++) {
40953e202c1Schristos 			aml_local_stack_getArgX(stack, i)->property =
41053e202c1Schristos 			    aml_alloc_object(argv[i].type, &argv[i]);
41153e202c1Schristos 		}
41253e202c1Schristos 		aml_local_stack_push(stack);
41353e202c1Schristos 		obj = aml_eval_name(env, tmp = aml_execute_method(env));
41453e202c1Schristos 		if (aml_debug) {
41553e202c1Schristos 			aml_showtree(name, 0);
41653e202c1Schristos 		}
41753e202c1Schristos 
41853e202c1Schristos 		if (tmp)
41953e202c1Schristos 			tmp->property = NULL;
42053e202c1Schristos 		aml_local_stack_delete(aml_local_stack_pop());
42153e202c1Schristos 		if (obj) {
42253e202c1Schristos 			aml_create_local_object()->property = obj;
42353e202c1Schristos 			retval = obj;
42453e202c1Schristos 		}
42553e202c1Schristos 	}
42653e202c1Schristos 	memman_free(aml_memman, memid_aml_environ, env);
42753e202c1Schristos 	return (retval);
42853e202c1Schristos }
42953e202c1Schristos 
43053e202c1Schristos union aml_object *
43153e202c1Schristos aml_invoke_method_by_name(char *method, int argc, union aml_object *argv)
43253e202c1Schristos {
43353e202c1Schristos 	struct	aml_name *name;
43453e202c1Schristos 
43553e202c1Schristos 	name = aml_find_from_namespace(aml_get_rootname(), method);
43653e202c1Schristos 	if (name == NULL) {
43753e202c1Schristos 		return (NULL);
43853e202c1Schristos 	}
43953e202c1Schristos 
44053e202c1Schristos 	return (aml_invoke_method(name, argc, argv));
44153e202c1Schristos }
442