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; }
/** 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; }
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; }