Beispiel #1
0
static void
vcc_Function(struct vcc *tl)
{
	int m, i;

	vcc_NextToken(tl);
	ExpectErr(tl, ID);

	m = IsMethod(tl->t);
	if (m != -1) {
		assert(m < VCL_MET_MAX);
		tl->fb = tl->fm[m];
		if (tl->mprocs[m] == NULL) {
			(void)vcc_AddDef(tl, tl->t, SYM_SUB);
			vcc_AddRef(tl, tl->t, SYM_SUB);
			tl->mprocs[m] = vcc_AddProc(tl, tl->t);
		}
		tl->curproc = tl->mprocs[m];
		Fb(tl, 1, "  /* ... from ");
		vcc_Coord(tl, tl->fb, NULL);
		Fb(tl, 0, " */\n");
	} else {
		tl->fb = tl->fc;
		i = vcc_AddDef(tl, tl->t, SYM_SUB);
		if (i > 1) {
			VSB_printf(tl->sb,
			    "Function %.*s redefined\n", PF(tl->t));
			vcc_ErrWhere(tl, tl->t);
			return;
		}
		tl->curproc = vcc_AddProc(tl, tl->t);
		Fh(tl, 0, "static int VGC_function_%.*s (struct sess *sp);\n",
		    PF(tl->t));
		Fc(tl, 1, "\nstatic int\n");
		Fc(tl, 1, "VGC_function_%.*s (struct sess *sp)\n", PF(tl->t));
	}
	vcc_NextToken(tl);
	tl->indent += INDENT;
	Fb(tl, 1, "{\n");
	L(tl, vcc_Compound(tl));
	if (m == -1) {
		/*
		 * non-method subroutines must have an explicit non-action
		 * return in case they just fall through the bottom.
		 */
		Fb(tl, 1, "  return(0);\n");
	}
	Fb(tl, 1, "}\n");
	tl->indent -= INDENT;
	tl->fb = NULL;
	tl->curproc = NULL;
}
Beispiel #2
0
/**
	setSlot( CLASS:Class, POSITION:Small, METHOD:Method )
	
	1. 	The method is inserted into the correct position in the class's
		slot array. To start with, only one method per slot will be
		permitted.
		
	2.	A call to setMethod is then made with an unsafe access function
		as the method's function. The values are passed on the stack. 
		No stack checks are needed as the size of the argument lists of
		the two functions are the same.
*/
Ref * sysSetSlot( Ref * pc, MachineClass * vm ) {
	if ( vm->count != 3 ) throw Ginger::Mishap( "Wrong number of arguments" );

	Ref method = vm->fastPop();
	Ref position = vm->fastPop();
	Ref gclass = vm->fastPop();

	if ( !IsMethod( method ) ) throw Ginger::Mishap( "Method needed" ).culprit( "Method", refToString( method ) );
	if ( !IsSmall( position ) ) throw Ginger::Mishap( "Small needed" ).culprit( "Position", refToString( position ) );
	if ( !IsClass( gclass ) ) throw Ginger::Mishap( "Class needed" ).culprit( "Class", refToString( gclass ) );
	
	long pos = SmallToLong( position );
	long nfields = SmallToLong( RefToPtr4( gclass )[ CLASS_OFFSET_NFIELDS ] );
	if ( not( 1 <= pos && pos <= nfields ) ) {
		throw 
			Ginger::Mishap( "Position out of range" ).
			culprit( "Position", pos ).
			culprit( "Number of fields", nfields )
		;
	}
	
	//	Update the class-slot.
	INDEX( INDEX( gclass, CLASS_OFFSET_SLOTS ), pos ) = method;

	//	Push onto the stack to get protection from garbage collection.
	vm->fastPush( gclass );
	vm->fastPush( method );

	//	ENDFUNCTION does not in fact cause a garbage collection, as it
	//	forces the heap to grow. However this is a more accurate way
	//	to write the code. 
	//
	//	The following block should not be in-lined but extracted as a 
	//	service function.
	{
		CodeGen codegen = vm->codegen();
		//	TODO: Supply a useful name.
		codegen->vmiFUNCTION( 1, 1 );
		codegen->vmiFIELD( pos );
		codegen->vmiSYS_RETURN();
		vm->fastPush( codegen->vmiENDFUNCTION() );
	}

	//	We do not need to modify vm->count, it's already 3.
	//	Simply chain into sysSetMethod. 
	return sysSetMethod( pc, vm );
}
JSBool
XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface,
                         JSObject *parent, jsval *vp)
{
    if (IsConstant()) {
        const nsXPTConstant* constant;
        if (NS_FAILED(iface->GetInterfaceInfo()->GetConstant(mIndex, &constant)))
            return false;

        const nsXPTCMiniVariant& mv = *constant->GetValue();

        // XXX Big Hack!
        nsXPTCVariant v;
        v.flags = 0;
        v.type = constant->GetType();
        memcpy(&v.val, &mv.val, sizeof(mv.val));

        jsval resultVal;

        if (!XPCConvert::NativeData2JS(ccx, &resultVal, &v.val, v.type,
                                       nsnull, nsnull))
            return false;

        *vp = resultVal;

        return true;
    }
    // else...

    // This is a method or attribute - we'll be needing a function object

    int argc;
    JSNative callback;

    if (IsMethod()) {
        const nsXPTMethodInfo* info;
        if (NS_FAILED(iface->GetInterfaceInfo()->GetMethodInfo(mIndex, &info)))
            return false;

        // Note: ASSUMES that retval is last arg.
        argc = (int) info->GetParamCount();
        if (argc && info->GetParam((uint8_t)(argc-1)).IsRetval())
            argc-- ;

        callback = XPC_WN_CallMethod;
    } else {
        argc = 0;
        callback = XPC_WN_GetterSetter;
    }

    JSFunction *fun = js::NewFunctionByIdWithReserved(ccx, callback, argc, 0, parent, GetName());
    if (!fun)
        return false;

    JSObject* funobj = JS_GetFunctionObject(fun);
    if (!funobj)
        return false;

    js::SetFunctionNativeReserved(funobj, 0, PRIVATE_TO_JSVAL(iface));
    js::SetFunctionNativeReserved(funobj, 1, PRIVATE_TO_JSVAL(this));

    *vp = OBJECT_TO_JSVAL(funobj);

    return true;
}
Beispiel #4
0
static void
vcc_ParseFunction(struct vcc *tl)
{
	int m, i;

	vcc_NextToken(tl);
	vcc_ExpectCid(tl, "function");
	ERRCHK(tl);

	m = IsMethod(tl->t);
	if (m == -2) {
		VSB_printf(tl->sb,
		    "VCL sub's named 'vcl*' are reserved names.\n");
		vcc_ErrWhere(tl, tl->t);
		VSB_printf(tl->sb, "Valid vcl_* methods are:\n");
		for (i = 1; method_tab[i].name != NULL; i++)
			VSB_printf(tl->sb, "\t%s\n", method_tab[i].name);
		return;
	} else if (m != -1) {
		assert(m < VCL_MET_MAX);
		tl->fb = tl->fm[m];
		if (tl->mprocs[m] == NULL) {
			(void)vcc_AddDef(tl, tl->t, SYM_SUB);
			vcc_AddRef(tl, tl->t, SYM_SUB);
			tl->mprocs[m] = vcc_AddProc(tl, tl->t);
		}
		tl->curproc = tl->mprocs[m];
		Fb(tl, 1, "  /* ... from ");
		vcc_Coord(tl, tl->fb, NULL);
		Fb(tl, 0, " */\n");
	} else {
		tl->fb = tl->fc;
		i = vcc_AddDef(tl, tl->t, SYM_SUB);
		if (i > 1) {
			VSB_printf(tl->sb,
			    "Function '%.*s' redefined\n", PF(tl->t));
			vcc_ErrWhere(tl, tl->t);
			return;
		}
		tl->curproc = vcc_AddProc(tl, tl->t);
		Fh(tl, 0, "int VGC_function_%.*s "
		    "(VRT_CTX);\n", PF(tl->t));
		Fc(tl, 1, "\nint __match_proto__(vcl_func_t)\n");
		Fc(tl, 1, "VGC_function_%.*s(VRT_CTX)\n",
		    PF(tl->t));
	}
	vcc_NextToken(tl);
	tl->indent += INDENT;
	Fb(tl, 1, "{\n");
	L(tl, vcc_Compound(tl));
	if (m == -1) {
		/*
		 * non-method subroutines must have an explicit non-action
		 * return in case they just fall through the bottom.
		 */
		Fb(tl, 1, "  return(0);\n");
	}
	Fb(tl, 1, "}\n");
	tl->indent -= INDENT;
	tl->fb = NULL;
	tl->curproc = NULL;
}
wxString TagEntry::FormatComment()
{
    if(m_isCommentForamtted) return m_formattedComment;
    m_isCommentForamtted = true;
    m_formattedComment.Clear();
    
    // Send the plugins an event requesting tooltip for this tag
    if(IsMethod()) {

        if(IsConstructor())
            m_formattedComment << wxT("<b>[Constructor]</b>\n");

        else if(IsDestructor())
            m_formattedComment << wxT("<b>[Destructor]</b>\n");

        TagEntryPtr p(new TagEntry(*this));
        m_formattedComment << wxT("<code>")
               << TagsManagerST::Get()->FormatFunction(p, FunctionFormat_WithVirtual | FunctionFormat_Arg_Per_Line)
               << wxT("</code>\n");
        m_formattedComment.Replace(GetName(), wxT("<b>") + GetName() + wxT("</b>"));
    } else if(IsClass()) {

        m_formattedComment << wxT("<b>Kind:</b> ");
        m_formattedComment << GetKind() << "\n";

        if(GetInheritsAsString().IsEmpty() == false) {
            m_formattedComment << wxT("<b>Inherits:</b> ");
            m_formattedComment << GetInheritsAsString() << wxT("\n");
        }

    } else if(IsMacro() || IsTypedef() || IsContainer() || GetKind() == wxT("member") ||
              GetKind() == wxT("variable")) {

        m_formattedComment << wxT("<b>Kind:</b> ");
        m_formattedComment << GetKind() << "\n";

        m_formattedComment << wxT("<b>Match Pattern:</b> ");

        // Prettify the match pattern
        wxString matchPattern(GetPattern());
        matchPattern.Trim().Trim(false);

        if(matchPattern.StartsWith(wxT("/^"))) {
            matchPattern.Replace(wxT("/^"), wxT(""));
        }

        if(matchPattern.EndsWith(wxT("$/"))) {
            matchPattern.Replace(wxT("$/"), wxT(""));
        }

        matchPattern.Replace(wxT("\t"), wxT(" "));
        while(matchPattern.Replace(wxT("  "), wxT(" "))) {
        }

        matchPattern.Trim().Trim(false);

        // BUG#3082954: limit the size of the 'match pattern' to a reasonable size (200 chars)
        matchPattern = TagsManagerST::Get()->WrapLines(matchPattern);
        matchPattern.Replace(GetName(), wxT("<b>") + GetName() + wxT("</b>"));
        m_formattedComment << wxT("<code>") << matchPattern << wxT("</code>\n");

    }

    // Add comment section
    wxString tagComment;
    if(!GetFile().IsEmpty()) {
        
        CommentParseResult comments;
        ::ParseComments(GetFile().mb_str(wxConvUTF8).data(), comments);
    
        // search for comment in the current line, the line above it and 2 above it
        // use the first match we got
        for(size_t i = 0; i < 3; i++) {
            wxString comment = comments.getCommentForLine(GetLine()-i);
            if(!comment.IsEmpty()) {
                SetComment(comment);
                break;
            }
        }
    }
    
    if(!GetComment().IsEmpty()) {
        wxString theComment;
        theComment = GetComment();

        theComment = TagsManagerST::Get()->WrapLines(theComment);
        theComment.Trim(false);
        wxString tagComment = wxString::Format(wxT("%s\n"), theComment.c_str());
        if(m_formattedComment.IsEmpty() == false) {
            m_formattedComment.Trim().Trim(false);
            m_formattedComment << wxT("\n<hr>");
        }
        m_formattedComment << tagComment;
    }

    // Update all "doxy" comments and surround them with <green> tags
    static wxRegEx reDoxyParam("([@\\\\]{1}param)[ \t]+([_a-z][a-z0-9_]*)?", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyBrief("([@\\\\]{1}(brief|details))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyThrow("([@\\\\]{1}(throw|throws))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyReturn("([@\\\\]{1}(return|retval|returns))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyToDo("([@\\\\]{1}todo)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyRemark("([@\\\\]{1}(remarks|remark))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDate("([@\\\\]{1}date)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reFN("([@\\\\]{1}fn)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);

    if(reDoxyParam.IsValid() && reDoxyParam.Matches(m_formattedComment)) {
        reDoxyParam.ReplaceAll(&m_formattedComment, "\n<b>Parameter</b>\n<i>\\2</i>");
    }

    if(reDoxyBrief.IsValid() && reDoxyBrief.Matches(m_formattedComment)) {
        reDoxyBrief.ReplaceAll(&m_formattedComment, "");
    }

    if(reDoxyThrow.IsValid() && reDoxyThrow.Matches(m_formattedComment)) {
        reDoxyThrow.ReplaceAll(&m_formattedComment, "\n<b>Throws</b>\n");
    }

    if(reDoxyReturn.IsValid() && reDoxyReturn.Matches(m_formattedComment)) {
        reDoxyReturn.ReplaceAll(&m_formattedComment, "\n<b>Returns</b>\n");
    }

    if(reDoxyToDo.IsValid() && reDoxyToDo.Matches(m_formattedComment)) {
        reDoxyToDo.ReplaceAll(&m_formattedComment, "\n<b>TODO</b>\n");
    }

    if(reDoxyRemark.IsValid() && reDoxyRemark.Matches(m_formattedComment)) {
        reDoxyRemark.ReplaceAll(&m_formattedComment, "\n  ");
    }

    if(reDate.IsValid() && reDate.Matches(m_formattedComment)) {
        reDate.ReplaceAll(&m_formattedComment, "<b>Date</b> ");
    }

    if(reFN.IsValid() && reFN.Matches(m_formattedComment)) {
        size_t fnStart, fnLen, fnEnd;
        if(reFN.GetMatch(&fnStart, &fnLen)) {
            fnEnd = m_formattedComment.find('\n', fnStart);
            if(fnEnd != wxString::npos) {
                // remove the string from fnStart -> fnEnd (including ther terminating \n)
                m_formattedComment.Remove(fnStart, (fnEnd - fnStart) + 1);
            }
        }
    }

    // if nothing to display skip this
    m_formattedComment.Trim().Trim(false);
    return m_formattedComment;
}
bool TagEntry::IsTemplateFunction() const 
{
    wxString pattern = GetPatternClean();
    pattern.Trim().Trim(false);
    return IsMethod() && pattern.StartsWith("template ");
}
JSBool
XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface)
{
    if(IsConstant())
    {
        const nsXPTConstant* constant;
        if(NS_FAILED(iface->GetInterfaceInfo()->GetConstant(mIndex, &constant)))
            return JS_FALSE;

        const nsXPTCMiniVariant& mv = *constant->GetValue();

        // XXX Big Hack!
        nsXPTCVariant v;
        v.flags = 0;
        v.type = constant->GetType();
        memcpy(&v.val, &mv.val, sizeof(mv.val));

        jsval resultVal;

        if(!XPCConvert::NativeData2JS(ccx, &resultVal, &v.val, v.type,
                                      nsnull, nsnull, nsnull))
            return JS_FALSE;

        {   // scoped lock
            XPCAutoLock lock(ccx.GetRuntime()->GetMapLock());
            mVal = resultVal;
            mFlags |= RESOLVED;
        }

        return JS_TRUE;
    }
    // else...

    // This is a method or attribute - we'll be needing a function object

    intN argc;
    intN flags;
    JSNative callback;

    if(IsMethod())
    {
        const nsXPTMethodInfo* info;
        if(NS_FAILED(iface->GetInterfaceInfo()->GetMethodInfo(mIndex, &info)))
            return JS_FALSE;

        // Note: ASSUMES that retval is last arg.
        argc = (intN) info->GetParamCount();
        if(argc && info->GetParam((uint8)(argc-1)).IsRetval())
            argc-- ;

        flags = 0;
        callback = XPC_WN_CallMethod;
    }
    else
    {
        if(IsWritableAttribute())
            flags = JSFUN_GETTER | JSFUN_SETTER;
        else
            flags = JSFUN_GETTER;
        argc = 0;
        callback = XPC_WN_GetterSetter;
    }

    // We need to use the safe context for this thread because we don't want
    // to parent the new (and cached forever!) function object to the current
    // JSContext's global object. That would be bad!

    JSContext* cx = ccx.GetSafeJSContext();
    if(!cx)
        return JS_FALSE;

    const char *memberName = iface->GetMemberName(ccx, this);

    jsrefcount suspendDepth = 0;
    if(cx != ccx) {
        // Switching contexts, suspend the old and enter the new request.
        suspendDepth = JS_SuspendRequest(ccx);
        JS_BeginRequest(cx);
    }

    JSFunction *fun = JS_NewFunction(cx, callback, argc, flags, nsnull,
                                     memberName);

    if(suspendDepth) {
        JS_EndRequest(cx);
        JS_ResumeRequest(ccx, suspendDepth);
    }

    if(!fun)
        return JS_FALSE;

    JSObject* funobj = JS_GetFunctionObject(fun);
    if(!funobj)
        return JS_FALSE;

    AUTO_MARK_JSVAL(ccx, OBJECT_TO_JSVAL(funobj));

    STOBJ_CLEAR_PARENT(funobj);
    STOBJ_CLEAR_PROTO(funobj);

    if(!JS_SetReservedSlot(ccx, funobj, 0, PRIVATE_TO_JSVAL(iface))||
       !JS_SetReservedSlot(ccx, funobj, 1, PRIVATE_TO_JSVAL(this)))
        return JS_FALSE;

    {   // scoped lock
        XPCAutoLock lock(ccx.GetRuntime()->GetMapLock());
        mVal = OBJECT_TO_JSVAL(funobj);
        mFlags |= RESOLVED;
    }

    return JS_TRUE;
}