diff options
| author | dkf <donal.k.fellows@manchester.ac.uk> | 2018-06-23 15:03:26 (GMT) |
|---|---|---|
| committer | dkf <donal.k.fellows@manchester.ac.uk> | 2018-06-23 15:03:26 (GMT) |
| commit | 05209c57d377b14758bda3882b0a70b979898066 (patch) | |
| tree | 2cbd3fa386325f56ebd8245d309463765202ef9c /generic/tclOOBasic.c | |
| parent | 8e696a5e5d19327336892388286b8d5d4fdc64a8 (diff) | |
| download | tcl-05209c57d377b14758bda3882b0a70b979898066.zip tcl-05209c57d377b14758bda3882b0a70b979898066.tar.gz tcl-05209c57d377b14758bda3882b0a70b979898066.tar.bz2 | |
Make the delegates work by moving their creation into C.
Diffstat (limited to 'generic/tclOOBasic.c')
| -rw-r--r-- | generic/tclOOBasic.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 763f0ad..54115e0 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -83,7 +83,7 @@ TclOO_Class_Constructor( Tcl_Obj *const *objv) { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); - Tcl_Obj **invoke; + Tcl_Obj **invoke, *nameObj; if (objc-1 > Tcl_ObjectContextSkippedArgs(context)) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, @@ -94,6 +94,17 @@ TclOO_Class_Constructor( } /* + * Make the class definition delegate. This is special; it doesn't reenter + * here (and the class definition delegate doesn't run any constructors). + */ + + nameObj = Tcl_NewStringObj(oPtr->namespacePtr->fullName, -1); + Tcl_AppendToObj(nameObj, ":: oo ::delegate", -1); + Tcl_NewObjectInstance(interp, (Tcl_Class) oPtr->fPtr->classCls, + TclGetString(nameObj), NULL, -1, NULL, -1); + Tcl_DecrRefCount(nameObj); + + /* * Delegate to [oo::define] to do the work. */ @@ -128,12 +139,17 @@ DecrRefsPostClassConstructor( int result) { Tcl_Obj **invoke = data[0]; + Tcl_InterpState saved; TclDecrRefCount(invoke[0]); - TclDecrRefCount(invoke[1]); TclDecrRefCount(invoke[2]); + invoke[0] = Tcl_NewStringObj("::oo::MixinClassDelegates", -1); + Tcl_IncrRefCount(invoke[0]); + saved = Tcl_SaveInterpState(interp, result); + Tcl_EvalObjv(interp, 2, invoke, 0); + TclDecrRefCount(invoke[1]); ckfree(invoke); - return result; + return Tcl_RestoreInterpState(interp, saved); } /* |
