-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdbo.Context.sql
140 lines (128 loc) · 2.39 KB
/
dbo.Context.sql
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
DROP TABLE IF EXISTS dbo.Stack
CREATE TABLE dbo.Stack
(
SPID int NOT NULL DEFAULT @@SPID,
Idx int NOT NULL,
Value int NOT NULL,
CONSTRAINT PK_Stack PRIMARY KEY CLUSTERED (SPID, Idx)
)
GO
CREATE OR ALTER VIEW vwStack
AS
SELECT *
FROM dbo.Stack
WHERE SPID = @@SPID
GO
DROP TABLE IF EXISTS dbo.Context
CREATE TABLE dbo.Context
(
SPID int PRIMARY KEY CLUSTERED, --SPID keyed table so we can support multiple programs executing at once.
StackPointer int NOT NULL,
ProgramCounter int NOT NULL
)
GO
CREATE OR ALTER VIEW vwContext
AS
SELECT *
FROM dbo.Context
WHERE SPID = @@SPID
GO
CREATE OR ALTER FUNCTION dbo.fnProgramCounterGet()
RETURNS int
AS
BEGIN
RETURN
(
SELECT TOP (1) ProgramCounter
FROM vwContext
)
END
GO
CREATE OR ALTER FUNCTION dbo.fnStackPointerGet()
RETURNS int
AS
BEGIN
RETURN
(
SELECT TOP (1) StackPointer
FROM dbo.vwContext
)
END
GO
CREATE OR ALTER PROCEDURE spContextInitialize
@StackPointer int = 0,
@ProgramCounter int = 0
AS
SET NOCOUNT, XACT_ABORT ON
BEGIN TRY
IF @StackPointer IS NULL
OR @ProgramCounter IS NULL
OR @StackPointer < 0
OR @ProgramCounter < 0
BEGIN
RAISERROR
(
N'Runtime Error (spContextInitialize): @StackPointer set to %d @ProgramCounter set to %d', 16, 1,
@StackPointer,
@ProgramCounter
) WITH NOWAIT
END
BEGIN TRAN
DELETE dbo.vwContext
INSERT dbo.Context
(
SPID,
StackPointer,
ProgramCounter
)
SELECT @@SPID,
@StackPointer,
@ProgramCounter
COMMIT TRAN
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 1 ROLLBACK TRAN
EXEC spErrorHandle
RETURN 651
END CATCH
GO
CREATE OR ALTER PROCEDURE spProgramCounterMove
@NewValue int = NULL
AS
SET NOCOUNT, XACT_ABORT ON
DECLARE @MaxLine int,
@NextLine int
-- If we aren't passed a new value, assume we're just going to the next instruction.
IF @NewValue IS NULL
BEGIN
SELECT @NextLine = dbo.fnProgramCounterGet() + 1
EXEC spProgramCounterMove
@NextLine
END
IF @NewValue < 1
OR NOT EXISTS
(
SELECT *
FROM dbo.vwRunningCode
WHERE LineNumber = @NewValue
)
BEGIN
SELECT @MaxLine = LineNumber
FROM vwRunningCode
RAISERROR
(
N'Runtime Error (spProgramCounterMove): Program Counter out of range. Specified %d expected value between 1 and %d', 16, 1,
@NextLine,
@MaxLine
) WITH NOWAIT
END
UPDATE vwContext
SET ProgramCounter = @NewValue
GO
CREATE OR ALTER PROCEDURE spStackPointerSet
@NewValue int
AS
SET NOCOUNT, XACT_ABORT ON
IF @NewValue IS NULL
RAISERROR
DELETE dbo.vwStack