-
Notifications
You must be signed in to change notification settings - Fork 751
Intern string #1254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Intern string #1254
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Python.Runtime | ||
{ | ||
static partial class InternString | ||
{ | ||
private static Dictionary<string, IntPtr> _string2interns; | ||
private static Dictionary<IntPtr, string> _intern2strings; | ||
|
||
static InternString() | ||
{ | ||
var identifierNames = typeof(PyIdentifier).GetFields().Select(fi => fi.Name); | ||
var validNames = new HashSet<string>(identifierNames); | ||
if (validNames.Count != _builtinNames.Length) | ||
{ | ||
throw new InvalidOperationException("Identifiers args not matching"); | ||
} | ||
foreach (var name in _builtinNames) | ||
{ | ||
if (!validNames.Contains(name)) | ||
{ | ||
throw new InvalidOperationException($"{name} is not declared"); | ||
} | ||
} | ||
} | ||
|
||
public static void Initialize() | ||
{ | ||
_string2interns = new Dictionary<string, IntPtr>(); | ||
_intern2strings = new Dictionary<IntPtr, string>(); | ||
|
||
Type type = typeof(PyIdentifier); | ||
foreach (string name in _builtinNames) | ||
{ | ||
IntPtr op = Runtime.PyUnicode_InternFromString(name); | ||
SetIntern(name, op); | ||
type.GetField(name).SetValue(null, op); | ||
} | ||
} | ||
|
||
public static void Shutdown() | ||
{ | ||
foreach (var ptr in _intern2strings.Keys) | ||
{ | ||
Runtime.XDecref(ptr); | ||
} | ||
_string2interns = null; | ||
_intern2strings = null; | ||
} | ||
|
||
public static string GetManagedString(IntPtr op) | ||
{ | ||
string s; | ||
if (TryGetInterned(op, out s)) | ||
{ | ||
return s; | ||
} | ||
return Runtime.GetManagedString(op); | ||
} | ||
|
||
public static bool TryGetInterned(IntPtr op, out string s) | ||
{ | ||
return _intern2strings.TryGetValue(op, out s); | ||
} | ||
|
||
private static void SetIntern(string s, IntPtr op) | ||
{ | ||
_string2interns.Add(s, op); | ||
_intern2strings.Add(op, s); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System; | ||
|
||
namespace Python.Runtime | ||
{ | ||
static class PyIdentifier | ||
{ | ||
public static IntPtr __name__; | ||
public static IntPtr __dict__; | ||
public static IntPtr __doc__; | ||
public static IntPtr __class__; | ||
public static IntPtr __module__; | ||
public static IntPtr __file__; | ||
public static IntPtr __slots__; | ||
public static IntPtr __self__; | ||
public static IntPtr __annotations__; | ||
public static IntPtr __init__; | ||
public static IntPtr __repr__; | ||
public static IntPtr __import__; | ||
public static IntPtr __builtins__; | ||
public static IntPtr builtins; | ||
public static IntPtr __overloads__; | ||
public static IntPtr Overloads; | ||
} | ||
|
||
|
||
static partial class InternString | ||
{ | ||
private static readonly string[] _builtinNames = new string[] | ||
{ | ||
"__name__", | ||
"__dict__", | ||
"__doc__", | ||
"__class__", | ||
"__module__", | ||
"__file__", | ||
"__slots__", | ||
"__self__", | ||
"__annotations__", | ||
"__init__", | ||
"__repr__", | ||
"__import__", | ||
"__builtins__", | ||
"builtins", | ||
"__overloads__", | ||
"Overloads", | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<#@ template debug="true" hostSpecific="true" #> | ||
<#@ output extension=".cs" #> | ||
<# | ||
string[] internNames = new string[] | ||
Comment on lines
+1
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why use a template generator, when you can simply get There was a problem hiding this comment. Choose a reason for hiding this comment111C The reason will be displayed to describe this comment to others. Learn more. Two reasons make this scenario happened.
const string s = "1";
switch (
case "1":
// both "1" point to the same string
break;
|
||
{ | ||
"__name__", | ||
"__dict__", | ||
"__doc__", | ||
"__class__", | ||
"__module__", | ||
"__file__", | ||
"__slots__", | ||
"__self__", | ||
"__annotations__", | ||
|
||
"__init__", | ||
"__repr__", | ||
"__import__", | ||
"__builtins__", | ||
|
||
"builtins", | ||
|
||
"__overloads__", | ||
"Overloads", | ||
}; | ||
#> | ||
using System; | ||
|
||
namespace Python.Runtime | ||
{ | ||
static class PyIdentifier | ||
{ | ||
<# | ||
foreach (var name in internNames) | ||
{ | ||
#> | ||
public static IntPtr <#= name #>; | ||
<# | ||
} | ||
#> | ||
} | ||
|
||
|
||
static partial class InternString | ||
{ | ||
private static readonly string[] _builtinNames = new string[] | ||
{ | ||
<# | ||
foreach (var name in internNames) | ||
{ | ||
#> | ||
"<#= name #>", | ||
<# | ||
} | ||
#> | ||
}; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.