added moo_ischildclassof().
filled pf_context_find_exception_handler() to speed up exception handling a bit
This commit is contained in:
		@ -221,7 +221,6 @@ pooldic MethodContext.Index
 | 
			
		||||
	// which translates to index 8 
 | 
			
		||||
	ENSURE := 8.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// [ ... ] on: Exception: do: [:ex | ... ]
 | 
			
		||||
	FIRST_ON := 8.
 | 
			
		||||
}
 | 
			
		||||
@ -252,7 +251,8 @@ extend MethodContext
 | 
			
		||||
		 * For a single on:do: call,
 | 
			
		||||
		 *   self class specNumInstVars must return 8.(i.e.MethodContext has 8 instance variables.)
 | 
			
		||||
		 *   basicAt: 8 must be the on: argument.
 | 
			
		||||
		 *   basicAt: 9 must be the do: argument  */
 | 
			
		||||
		 *   basicAt: 9 must be the do: argument
 | 
			
		||||
		 */
 | 
			
		||||
		| size exc i |
 | 
			
		||||
 | 
			
		||||
		<primitive: #MethodContext_findExceptionHandler:>
 | 
			
		||||
@ -261,7 +261,12 @@ extend MethodContext
 | 
			
		||||
		{
 | 
			
		||||
			/* NOTE: the following loop scans all parameters to the on:do: method.
 | 
			
		||||
			 *       if the on:do: method contains local temporary variables,
 | 
			
		||||
			 *       those must be skipped from scanning. */
 | 
			
		||||
			 *       you must change this function to skip scanning local variables. 
 | 
			
		||||
			 *       the current on:do: method has 1 local variable declared.
 | 
			
		||||
			 *       as local variables are placed after method arguments and 
 | 
			
		||||
			 *       the loop increments 'i' by 2, the last element is naturally
 | 
			
		||||
			 *       get excluded from inspection.
 | 
			
		||||
			 */
 | 
			
		||||
			size := self basicSize.
 | 
			
		||||
 | 
			
		||||
			// start scanning from the position of the first parameter
 | 
			
		||||
@ -368,6 +373,22 @@ thisContext isExceptionContext dump.
 | 
			
		||||
		^self value.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	method on: exc1 do: blk1 on: exc2 do: blk2 on: exc3 do: blk3 on: exc4 do: blk4
 | 
			
		||||
	{
 | 
			
		||||
		| exception_active |
 | 
			
		||||
		<exception>
 | 
			
		||||
		exception_active := true.
 | 
			
		||||
		^self value.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	method on: exc1 do: blk1 on: exc2 do: blk2 on: exc3 do: blk3 on: exc4 do: blk4 on: exc5 do: blk5
 | 
			
		||||
	{
 | 
			
		||||
		| exception_active |
 | 
			
		||||
		<exception>
 | 
			
		||||
		exception_active := true.
 | 
			
		||||
		^self value.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	method ensure: aBlock
 | 
			
		||||
	{
 | 
			
		||||
		| retval pending |
 | 
			
		||||
 | 
			
		||||
@ -2172,7 +2172,46 @@ static moo_pfrc_t pf_context_goto (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
 | 
			
		||||
 | 
			
		||||
static moo_pfrc_t pf_context_find_exception_handler (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
 | 
			
		||||
{
 | 
			
		||||
	return MOO_PF_FAILURE;
 | 
			
		||||
	moo_oop_context_t rcv;
 | 
			
		||||
	moo_ooi_t preamble;
 | 
			
		||||
	moo_oop_t except_class;
 | 
			
		||||
 | 
			
		||||
	rcv = (moo_oop_context_t)MOO_STACK_GETRCV(moo, nargs);
 | 
			
		||||
	MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_method_context);
 | 
			
		||||
 | 
			
		||||
	preamble = MOO_OOP_TO_SMOOI(((moo_oop_method_t)rcv->method_or_nargs)->preamble);
 | 
			
		||||
	if (MOO_METHOD_GET_PREAMBLE_CODE(preamble) == MOO_METHOD_PREAMBLE_EXCEPTION)
 | 
			
		||||
	{
 | 
			
		||||
		/* <exception> context 
 | 
			
		||||
		 * on: ... do: ...*/
 | 
			
		||||
		moo_oow_t size, i;
 | 
			
		||||
 | 
			
		||||
		except_class = MOO_STACK_GETARG(moo, nargs, 0);
 | 
			
		||||
 | 
			
		||||
		size = MOO_OBJ_GET_SIZE(rcv);
 | 
			
		||||
		for (i = MOO_CONTEXT_NAMED_INSTVARS; i < size; i += 2)
 | 
			
		||||
		{
 | 
			
		||||
			/* NOTE: the following loop scans all parameters to the on:do: method.
 | 
			
		||||
			 *       if the on:do: method contains local temporary variables,
 | 
			
		||||
			 *       you must change this function to skip scanning local variables. 
 | 
			
		||||
			 *       the current on:do: method has 1 local variable declared.
 | 
			
		||||
			 *       as local variables are placed after method arguments and 
 | 
			
		||||
			 *       the loop increments 'i' by 2, the last element is naturally
 | 
			
		||||
			 *       get excluded from inspection.
 | 
			
		||||
			 */
 | 
			
		||||
			moo_oop_class_t on_class;
 | 
			
		||||
 | 
			
		||||
			on_class = (moo_oop_class_t)MOO_OBJ_GET_OOP_VAL(rcv, i);
 | 
			
		||||
			if (on_class == except_class || (MOO_CLASSOF(moo, on_class) == moo->_class && moo_ischildclassof(moo, except_class, on_class)))
 | 
			
		||||
			{
 | 
			
		||||
				MOO_STACK_SETRET (moo, nargs, MOO_OBJ_GET_OOP_VAL(rcv, i + 1));
 | 
			
		||||
				return MOO_PF_SUCCESS;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	MOO_STACK_SETRET (moo, nargs, moo->_nil);
 | 
			
		||||
	return MOO_PF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
@ -1066,3 +1066,15 @@ int moo_iskindof (moo_t* moo, moo_oop_t obj, moo_oop_class_t _class)
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int moo_ischildclassof (moo_t* moo, moo_oop_class_t c, moo_oop_class_t k)
 | 
			
		||||
{
 | 
			
		||||
	c = (moo_oop_class_t)c->superclass;
 | 
			
		||||
	while ((moo_oop_t)c != moo->_nil)
 | 
			
		||||
	{
 | 
			
		||||
		if (c == k) return 1;
 | 
			
		||||
		c = (moo_oop_class_t)c->superclass;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2123,6 +2123,13 @@ MOO_EXPORT int moo_iskindof (
 | 
			
		||||
	moo_oop_class_t _class
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/* check if c is a child class of k */
 | 
			
		||||
MOO_EXPORT int moo_ischildclassof (
 | 
			
		||||
	moo_t*          moo,
 | 
			
		||||
	moo_oop_class_t c,
 | 
			
		||||
	moo_oop_class_t k
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/* =========================================================================
 | 
			
		||||
 * TRAILER MANAGEMENT
 | 
			
		||||
 * ========================================================================= */
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user