private CPythonType LookupType(object type) { if (type != null) { object[] typeInfo = (object[])type; if (typeInfo.Length == 2) { string modName = typeInfo[0] as string; string typeName = typeInfo[1] as string; if (modName != null) { if (typeName != null) { var module = GetModule(modName); if (module != null) { return(module.GetAnyMember(typeName) as CPythonType); } } } } } else { return(BuiltinModule.GetAnyMember("object") as CPythonType); } return(null); }
private IPythonType RunObjectTypeFixups() { var objectType = Volatile.Read(ref _objectType); if (objectType == null) { var newObjectType = BuiltinModule.GetAnyMember(GetBuiltinTypeName(BuiltinTypeId.Object)) as IPythonType; if (newObjectType == null) { // No type available, so don't do fixups return(null); } // Either set _objectType to newObjectType, or replace our local // objectType with whatever got there first objectType = Interlocked.CompareExchange(ref _objectType, newObjectType, null) ?? newObjectType; } var fixups = _objectTypeFixups; if (fixups != null) { lock (fixups) { if (!ReferenceEquals(_objectTypeFixups, fixups)) { // _objectTypeFixups changed while we waited to lock // This means someone else now owns the list and will // run the fixups, so we can just return the new object // type. return(objectType); } _objectTypeFixups = null; } // At this point, nobody else has a reference to the list. If // they did (see AddObjectTypeFixup), they just entered the lock // now and discovered that _objectTypeFixups has changed and // will not use the reference they have. foreach (var assign in fixups) { assign(objectType); } } return(objectType); }
private void RunObjectTypeFixups() { if (_objectType == null) { _objectType = BuiltinModule.GetAnyMember(GetBuiltinTypeName(BuiltinTypeId.Object)) as IPythonType; if (_objectType != null) { var fixups = _objectTypeFixups; _objectTypeFixups = null; if (fixups != null) { foreach (var assign in fixups) { assign(_objectType); } } } } }
/// <summary> /// Looks up a type and queues a fixup if the type is not yet available. Receives a delegate /// which assigns the value to the appropriate field. /// </summary> public void LookupType(object type, Action <CPythonType> assign) { var value = LookupType(type); if (value == null) { AddFixup( () => { var delayedType = LookupType(type); if (delayedType == null) { delayedType = BuiltinModule.GetAnyMember("object") as CPythonType; } Debug.Assert(delayedType != null); assign(delayedType); } ); } else { assign(value); } }
/// <summary> /// Looks up a type and queues a fixup if the type is not yet available. /// Receives a delegate which assigns the value to the appropriate field. /// </summary> public void LookupType(object typeRefOrList, Action <IPythonType> assign) { var typeRef = typeRefOrList as object[]; if (typeRef != null && typeRef.Length >= 2) { string modName = null, typeName = null; List <object> indexTypes = null; IPythonType res = null; modName = typeRef[0] as string; typeName = typeRef[1] as string; if (typeRef.Length > 2) { indexTypes = typeRef[2] as List <object>; } if (typeName == null) { Debug.Assert(modName == null, "moduleref should not be passed to LookupType"); AddObjectTypeFixup(assign); return; } else { IPythonModule module; if (modName == null) { res = BuiltinModule.GetAnyMember(typeName) as IPythonType; if (res != null) { assign(res); } else { AddObjectTypeFixup(assign); } } else { string alternateTypeName = typeName; module = GetModuleOrClass(modName, ref alternateTypeName); if (module == null) { AddFixup(() => { // Fixup 1: Module was not found. var mod2 = GetModuleOrClass(modName, ref alternateTypeName); if (mod2 != null) { AssignMemberFromModule(mod2, alternateTypeName, null, indexTypes, assign, true); } }); return; } AssignMemberFromModule(module, alternateTypeName, null, indexTypes, assign, true); } } return; } var multiple = typeRefOrList as List <object>; if (multiple != null) { foreach (var typeInfo in multiple) { LookupType(typeInfo, assign); } } }