forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPythonGlobal.cs
More file actions
126 lines (103 loc) · 3.75 KB
/
PythonGlobal.cs
File metadata and controls
126 lines (103 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Diagnostics;
using System.Reflection;
using Microsoft.Scripting;
using Microsoft.Scripting.Ast;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
namespace IronPython.Compiler {
/// <summary>
/// Provides cached global variable for modules to enable optimized access to
/// module globals. Both the module global value and the cached value can be held
/// onto and the cached value can be invalidated by the providing LanguageContext.
///
/// The cached value is provided by the LanguageContext.GetModuleCache API.
/// </summary>
[DebuggerDisplay("{Display}")]
public sealed class PythonGlobal {
private object? _value;
private ModuleGlobalCache? _global;
private readonly string _name;
private readonly CodeContext/*!*/ _context;
internal static PropertyInfo/*!*/ CurrentValueProperty = typeof(PythonGlobal).GetProperty(nameof(CurrentValue))!;
internal static PropertyInfo/*!*/ RawValueProperty = typeof(PythonGlobal).GetProperty(nameof(RawValue))!;
public PythonGlobal(CodeContext/*!*/ context, string name) {
Assert.NotNull(context);
_value = Uninitialized.Instance;
_context = context;
_name = name;
}
public object? CurrentValue {
get {
if (_value != Uninitialized.Instance) {
return _value;
}
return GetCachedValue(false);
}
set {
if (value == Uninitialized.Instance && _value == Uninitialized.Instance) {
throw PythonOps.GlobalNameError(_name);
}
_value = value;
}
}
public object? CurrentValueLightThrow {
get {
if (_value != Uninitialized.Instance) {
return _value;
}
return GetCachedValue(true);
}
}
public string Name => _name;
private object? GetCachedValue(bool lightThrow) {
_global ??= _context.LanguageContext.GetModuleGlobalCache(_name);
if (_global.IsCaching) {
if (_global.HasValue) {
return _global.Value;
}
} else {
if (_context.TryLookupBuiltin(_name, out object? value)) {
return value;
}
}
var ex = PythonOps.NameError(_name);
if (lightThrow) {
return LightExceptions.Throw(ex);
}
throw ex;
}
public object? RawValue {
get {
return _value;
}
internal set {
_value = value;
}
}
public string Display {
get {
try {
return GetStringDisplay(CurrentValue);
} catch (MissingMemberException) {
return "<uninitialized>";
}
}
}
private static string GetStringDisplay(object? val) {
return val is null ? "(null)" : val.ToString() ?? "<no representation>";
}
public override string ToString() {
return string.Format("ModuleGlobal: {0} Value: {1} ({2})",
_name,
_value,
RawValue == Uninitialized.Instance ? "Module Local" : "Global");
}
}
}