Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
d7ace789
Commit
d7ace789
authored
Aug 17, 2004
by
pem@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/home/pem/work/mysql-5.0-merge
parents
f1e280e2
38b4cbbb
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
482 additions
and
39 deletions
+482
-39
mysql-test/r/sp-error.result
mysql-test/r/sp-error.result
+5
-0
mysql-test/r/sp.result
mysql-test/r/sp.result
+85
-4
mysql-test/t/sp-error.test
mysql-test/t/sp-error.test
+6
-1
mysql-test/t/sp.test
mysql-test/t/sp.test
+61
-2
sql/lex.h
sql/lex.h
+2
-0
sql/sp_head.cc
sql/sp_head.cc
+29
-4
sql/sp_head.h
sql/sp_head.h
+39
-3
sql/sp_pcontext.cc
sql/sp_pcontext.cc
+78
-4
sql/sp_pcontext.h
sql/sp_pcontext.h
+48
-3
sql/sql_yacc.yy
sql/sql_yacc.yy
+129
-18
No files found.
mysql-test/r/sp-error.result
View file @
d7ace789
...
...
@@ -63,6 +63,11 @@ iterate foo;
end|
ERROR 42000: ITERATE with no matching label: foo
create procedure foo()
begin
goto foo;
end|
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
foo: loop
foo: loop
set @x=2;
...
...
mysql-test/r/sp.result
View file @
d7ace789
...
...
@@ -398,6 +398,87 @@ id data
i 3
delete from t1|
drop procedure i|
create procedure j()
begin
declare y int;
label a;
select * from t1;
select count(*) into y from t1;
if y > 2 then
goto b;
end if;
insert into t1 values ("j", y);
goto a;
label b;
end|
call j()|
id data
id data
j 0
id data
j 0
j 1
id data
j 0
j 1
j 2
drop procedure j|
create procedure k(a int)
begin
declare x int default 0;
declare continue handler for sqlstate '42S98' set x = 1;
label a;
select * from t1;
b:
while x < 2 do
begin
declare continue handler for sqlstate '42S99' set x = 2;
if a = 0 then
set x = x + 1;
iterate b;
elseif a = 1 then
leave b;
elseif a = 2 then
set a = 1;
goto a;
end if;
end;
end while b;
select * from t1;
end|
call k(0)|
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call k(1)|
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call k(2)|
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
drop procedure k|
delete from t1|
insert into t1 values ("foo", 3), ("bar", 19)|
insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
create procedure sel1()
...
...
@@ -1487,7 +1568,7 @@ Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 22
185
master-bin.000001 22
451
Database Table In_use Name_locked
Privilege Context Comment
Alter Tables To alter the table
...
...
@@ -1541,7 +1622,7 @@ Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 22
185
master-bin.000001 22
451
Database Table In_use Name_locked
Privilege Context Comment
Alter Tables To alter the table
...
...
@@ -1580,10 +1661,10 @@ show processlist;
end|
call bug4902_2()|
Id User Host db Command Time State Info
# root localhost test Query
0
NULL call bug4902_2()
# root localhost test Query
#
NULL call bug4902_2()
call bug4902_2()|
Id User Host db Command Time State Info
# root localhost test Query
0
NULL call bug4902_2()
# root localhost test Query
#
NULL call bug4902_2()
drop procedure bug4902_2|
drop table if exists t3|
create procedure bug4904()
...
...
mysql-test/t/sp-error.test
View file @
d7ace789
...
...
@@ -82,7 +82,7 @@ drop procedure if exists foo|
--
error
1304
show
create
procedure
foo
|
# LEAVE/ITERATE with no match
# LEAVE/ITERATE
/GOTO
with no match
--
error
1307
create
procedure
foo
()
foo
:
loop
...
...
@@ -98,6 +98,11 @@ create procedure foo()
foo
:
begin
iterate
foo
;
end
|
--
error
1307
create
procedure
foo
()
begin
goto
foo
;
end
|
# Redefining label
--
error
1308
...
...
mysql-test/t/sp.test
View file @
d7ace789
...
...
@@ -468,6 +468,65 @@ delete from t1|
drop
procedure
i
|
# The non-standard GOTO, for compatibility
#
# QQQ The "label" syntax is temporary.
# QQQ This is no nearly enough, more tests are needed
#
create
procedure
j
()
begin
declare
y
int
;
label
a
;
select
*
from
t1
;
select
count
(
*
)
into
y
from
t1
;
if
y
>
2
then
goto
b
;
end
if
;
insert
into
t1
values
(
"j"
,
y
);
goto
a
;
label
b
;
end
|
call
j
()
|
drop
procedure
j
|
# With dummy handlers, just to test restore of contexts with jumps
create
procedure
k
(
a
int
)
begin
declare
x
int
default
0
;
declare
continue
handler
for
sqlstate
'42S98'
set
x
=
1
;
label
a
;
select
*
from
t1
;
b
:
while
x
<
2
do
begin
declare
continue
handler
for
sqlstate
'42S99'
set
x
=
2
;
if
a
=
0
then
set
x
=
x
+
1
;
iterate
b
;
elseif
a
=
1
then
leave
b
;
elseif
a
=
2
then
set
a
=
1
;
goto
a
;
end
if
;
end
;
end
while
b
;
select
*
from
t1
;
end
|
call
k
(
0
)
|
call
k
(
1
)
|
call
k
(
2
)
|
drop
procedure
k
|
delete
from
t1
|
# SELECT with one of more result set sent back to the clinet
insert
into
t1
values
(
"foo"
,
3
),
(
"bar"
,
19
)
|
insert
into
t2
values
(
"x"
,
9
,
4.1
),
(
"y"
,
-
1
,
19.2
),
(
"z"
,
3
,
2.2
)
|
...
...
@@ -1725,9 +1784,9 @@ create procedure bug4902_2()
begin
show
processlist
;
end
|
--
replace_column
1
#
--
replace_column
1
#
6 #
call
bug4902_2
()
|
--
replace_column
1
#
--
replace_column
1
#
6 #
call
bug4902_2
()
|
drop
procedure
bug4902_2
|
...
...
sql/lex.h
View file @
d7ace789
...
...
@@ -209,6 +209,7 @@ static SYMBOL symbols[] = {
{
"GEOMETRYCOLLECTION"
,
SYM
(
GEOMETRYCOLLECTION
)},
{
"GET_FORMAT"
,
SYM
(
GET_FORMAT
)},
{
"GLOBAL"
,
SYM
(
GLOBAL_SYM
)},
{
"GOTO"
,
SYM
(
GOTO_SYM
)},
{
"GRANT"
,
SYM
(
GRANT
)},
{
"GRANTS"
,
SYM
(
GRANTS
)},
{
"GROUP"
,
SYM
(
GROUP
)},
...
...
@@ -256,6 +257,7 @@ static SYMBOL symbols[] = {
{
"KEY"
,
SYM
(
KEY_SYM
)},
{
"KEYS"
,
SYM
(
KEYS
)},
{
"KILL"
,
SYM
(
KILL_SYM
)},
{
"LABEL"
,
SYM
(
LABEL_SYM
)},
{
"LANGUAGE"
,
SYM
(
LANGUAGE_SYM
)},
{
"LAST"
,
SYM
(
LAST_SYM
)},
{
"LEADING"
,
SYM
(
LEADING
)},
...
...
sql/sp_head.cc
View file @
d7ace789
...
...
@@ -846,14 +846,38 @@ sp_head::backpatch(sp_label_t *lab)
List_iterator_fast
<
bp_t
>
li
(
m_backpatch
);
while
((
bp
=
li
++
))
if
(
bp
->
lab
==
lab
)
{
sp_instr_jump
*
i
=
static_cast
<
sp_instr_jump
*>
(
bp
->
instr
);
if
(
bp
->
lab
==
lab
||
(
bp
->
lab
->
type
==
SP_LAB_REF
&&
my_strcasecmp
(
system_charset_info
,
bp
->
lab
->
name
,
lab
->
name
)
==
0
))
{
sp_scope_t
sdiff
;
i
->
set_destination
(
dest
);
if
(
bp
->
lab
->
type
==
SP_LAB_REF
)
bp
->
lab
=
lab
;
m_pcont
->
diff_scopes
(
0
,
&
sdiff
);
bp
->
instr
->
backpatch
(
dest
,
sdiff
.
hndlrs
,
sdiff
.
curs
);
}
}
}
int
sp_head
::
check_backpatch
(
THD
*
thd
)
{
bp_t
*
bp
;
List_iterator_fast
<
bp_t
>
li
(
m_backpatch
);
while
((
bp
=
li
++
))
{
if
(
bp
->
lab
->
type
==
SP_LAB_REF
)
{
net_printf
(
thd
,
ER_SP_LILABEL_MISMATCH
,
"GOTO"
,
bp
->
lab
->
name
);
return
-
1
;
}
}
return
0
;
}
void
sp_head
::
set_info
(
char
*
definer
,
uint
definerlen
,
longlong
created
,
longlong
modified
,
...
...
@@ -1199,8 +1223,9 @@ sp_instr_jump::print(String *str)
uint
sp_instr_jump
::
opt_mark
(
sp_head
*
sp
)
{
marked
=
1
;
m_dest
=
opt_shortcut_jump
(
sp
);
if
(
m_dest
!=
m_ip
+
1
)
/* Jumping to following instruction? */
marked
=
1
;
m_optdest
=
sp
->
get_instr
(
m_dest
);
return
m_dest
;
}
...
...
sql/sp_head.h
View file @
d7ace789
...
...
@@ -182,6 +182,13 @@ public:
void
backpatch
(
struct
sp_label
*
);
// Check that no unresolved references exist.
// If none found, 0 is returned, otherwise errors have been issued
// and -1 is returned.
// This is called by the parser at the end of a create procedure/function.
int
check_backpatch
(
THD
*
thd
);
char
*
name
(
uint
*
lenp
=
0
)
const
{
if
(
lenp
)
...
...
@@ -272,7 +279,7 @@ public:
virtual
void
print
(
String
*
str
)
=
0
;
virtual
void
set_destination
(
uint
dest
)
virtual
void
backpatch
(
uint
dest
,
uint
hpop
,
uint
cpop
)
{}
virtual
uint
opt_mark
(
sp_head
*
sp
)
...
...
@@ -394,8 +401,7 @@ public:
virtual
void
opt_move
(
uint
dst
,
List
<
sp_instr
>
*
ibp
);
virtual
void
set_destination
(
uint
dest
)
virtual
void
backpatch
(
uint
dest
,
uint
hpop
,
uint
cpop
)
{
if
(
m_dest
==
0
)
// Don't reset
m_dest
=
dest
;
...
...
@@ -575,6 +581,21 @@ public:
virtual
void
print
(
String
*
str
);
virtual
void
backpatch
(
uint
dest
,
uint
hpop
,
uint
cpop
)
{
if
(
hpop
>
m_count
)
m_count
=
0
;
else
m_count
-=
hpop
;
}
virtual
uint
opt_mark
(
sp_head
*
sp
)
{
if
(
m_count
)
marked
=
1
;
return
m_ip
+
1
;
}
private:
uint
m_count
;
...
...
@@ -655,6 +676,21 @@ public:
virtual
void
print
(
String
*
str
);
virtual
void
backpatch
(
uint
dest
,
uint
hpop
,
uint
cpop
)
{
if
(
cpop
>
m_count
)
m_count
=
0
;
else
m_count
-=
cpop
;
}
virtual
uint
opt_mark
(
sp_head
*
sp
)
{
if
(
m_count
)
marked
=
1
;
return
m_ip
+
1
;
}
private:
uint
m_count
;
...
...
sql/sp_pcontext.cc
View file @
d7ace789
...
...
@@ -27,12 +27,14 @@
#include "sp_head.h"
sp_pcontext
::
sp_pcontext
()
:
Sql_alloc
(),
m_params
(
0
),
m_framesize
(
0
),
m_handlers
(
0
),
m_cursmax
(
0
)
:
Sql_alloc
(),
m_params
(
0
),
m_framesize
(
0
),
m_handlers
(
0
),
m_cursmax
(
0
),
m_hndlrlev
(
0
)
{
VOID
(
my_init_dynamic_array
(
&
m_pvar
,
sizeof
(
sp_pvar_t
*
),
16
,
8
));
VOID
(
my_init_dynamic_array
(
&
m_cond
,
sizeof
(
sp_cond_type_t
*
),
16
,
8
));
VOID
(
my_init_dynamic_array
(
&
m_cursor
,
sizeof
(
LEX_STRING
),
16
,
8
));
VOID
(
my_init_dynamic_array
(
&
m_scopes
,
sizeof
(
sp_scope_t
),
16
,
8
));
VOID
(
my_init_dynamic_array
(
&
m_glabel
,
sizeof
(
sp_label_t
*
),
16
,
8
));
m_label
.
empty
();
}
...
...
@@ -43,6 +45,7 @@ sp_pcontext::destroy()
delete_dynamic
(
&
m_cond
);
delete_dynamic
(
&
m_cursor
);
delete_dynamic
(
&
m_scopes
);
delete_dynamic
(
&
m_glabel
);
m_label
.
empty
();
}
...
...
@@ -53,14 +56,46 @@ sp_pcontext::push_scope()
s
.
vars
=
m_pvar
.
elements
;
s
.
conds
=
m_cond
.
elements
;
s
.
hndlrs
=
m_hndlrlev
;
s
.
curs
=
m_cursor
.
elements
;
s
.
glab
=
m_glabel
.
elements
;
insert_dynamic
(
&
m_scopes
,
(
gptr
)
&
s
);
}
void
sp_pcontext
::
pop_scope
()
sp_pcontext
::
pop_scope
(
sp_scope_t
*
sp
)
{
(
void
)
pop_dynamic
(
&
m_scopes
);
byte
*
p
=
pop_dynamic
(
&
m_scopes
);
if
(
sp
&&
p
)
memcpy
(
sp
,
p
,
sizeof
(
sp_scope_t
));
}
void
sp_pcontext
::
diff_scopes
(
uint
sold
,
sp_scope_t
*
diffs
)
{
uint
snew
=
m_scopes
.
elements
;
sp_scope_t
scope
;
diffs
->
vars
=
diffs
->
conds
=
diffs
->
hndlrs
=
diffs
->
curs
=
diffs
->
glab
=
0
;
while
(
snew
--
>
sold
)
{
get_dynamic
(
&
m_scopes
,
(
gptr
)
&
scope
,
snew
);
diffs
->
vars
+=
scope
.
vars
;
diffs
->
conds
+=
scope
.
conds
;
diffs
->
hndlrs
+=
scope
.
hndlrs
;
diffs
->
curs
+=
scope
.
curs
;
diffs
->
glab
+=
scope
.
glab
;
}
if
(
sold
)
{
get_dynamic
(
&
m_scopes
,
(
gptr
)
&
scope
,
sold
-
1
);
diffs
->
vars
-=
scope
.
vars
;
diffs
->
conds
-=
scope
.
conds
;
diffs
->
hndlrs
-=
scope
.
hndlrs
;
diffs
->
curs
-=
scope
.
curs
;
diffs
->
glab
-=
scope
.
glab
;
}
}
...
...
@@ -132,7 +167,8 @@ sp_pcontext::push_label(char *name, uint ip)
{
lab
->
name
=
name
;
lab
->
ip
=
ip
;
lab
->
isbegin
=
FALSE
;
lab
->
type
=
SP_LAB_GOTO
;
lab
->
scopes
=
0
;
m_label
.
push_front
(
lab
);
}
return
lab
;
...
...
@@ -245,3 +281,41 @@ sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped)
}
return
FALSE
;
}
sp_label_t
*
sp_pcontext
::
push_glabel
(
char
*
name
,
uint
ip
)
{
sp_label_t
*
lab
=
(
sp_label_t
*
)
sql_alloc
(
sizeof
(
sp_label_t
));
if
(
lab
)
{
lab
->
name
=
name
;
lab
->
ip
=
ip
;
lab
->
type
=
SP_LAB_GOTO
;
lab
->
scopes
=
0
;
insert_dynamic
(
&
m_glabel
,
(
gptr
)
&
lab
);
}
return
lab
;
}
sp_label_t
*
sp_pcontext
::
find_glabel
(
char
*
name
)
{
uint
i
=
m_glabel
.
elements
;
while
(
i
--
)
{
sp_label_t
*
lab
;
get_dynamic
(
&
m_glabel
,
(
gptr
)
&
lab
,
i
);
if
(
my_strcasecmp
(
system_charset_info
,
name
,
lab
->
name
)
==
0
)
return
lab
;
}
return
NULL
;
}
void
sp_pcontext
::
pop_glabel
(
uint
count
)
{
(
void
)
pop_dynamic
(
&
m_glabel
);
}
sql/sp_pcontext.h
View file @
d7ace789
...
...
@@ -39,11 +39,18 @@ typedef struct sp_pvar
Item
*
dflt
;
}
sp_pvar_t
;
#define SP_LAB_REF 0 // Unresolved reference (for goto)
#define SP_LAB_GOTO 1 // Free goto label
#define SP_LAB_BEGIN 2 // Label at BEGIN
#define SP_LAB_ITER 3 // Label at iteration control
typedef
struct
sp_label
{
char
*
name
;
uint
ip
;
// Instruction index
my_bool
isbegin
;
// For ITERATE error checking
int
type
;
// begin/iter or ref/free
uint
scopes
;
// No. of scopes at label
}
sp_label_t
;
typedef
struct
sp_cond_type
...
...
@@ -61,7 +68,7 @@ typedef struct sp_cond
typedef
struct
sp_scope
{
uint
vars
,
conds
,
curs
;
uint
vars
,
conds
,
hndlrs
,
curs
,
glab
;
}
sp_scope_t
;
class
sp_pcontext
:
public
Sql_alloc
...
...
@@ -82,7 +89,18 @@ class sp_pcontext : public Sql_alloc
push_scope
();
void
pop_scope
();
pop_scope
(
sp_scope_t
*
sp
=
0
);
uint
scopes
()
{
return
m_scopes
.
elements
;
}
// Sets '*diffs' to the differences between current scope index snew and sold
void
diff_scopes
(
uint
sold
,
sp_scope_t
*
diffs
);
//
// Parameters and variables
...
...
@@ -223,6 +241,18 @@ class sp_pcontext : public Sql_alloc
return
m_handlers
;
}
inline
void
push_handlers
(
uint
count
)
{
m_hndlrlev
+=
count
;
}
inline
void
pop_handlers
(
uint
count
)
{
m_hndlrlev
-=
count
;
}
//
// Cursors
//
...
...
@@ -246,17 +276,32 @@ class sp_pcontext : public Sql_alloc
return
m_cursmax
;
}
//
// GOTO labels
//
sp_label_t
*
push_glabel
(
char
*
name
,
uint
ip
);
sp_label_t
*
find_glabel
(
char
*
name
);
void
pop_glabel
(
uint
count
);
private:
uint
m_params
;
// The number of parameters
uint
m_framesize
;
// The maximum framesize
uint
m_handlers
;
// The total number of handlers
uint
m_cursmax
;
// The maximum number of cursors
uint
m_hndlrlev
;
// Current number of active handlers
DYNAMIC_ARRAY
m_pvar
;
// Parameters/variables
DYNAMIC_ARRAY
m_cond
;
// Conditions
DYNAMIC_ARRAY
m_cursor
;
// Cursors
DYNAMIC_ARRAY
m_scopes
;
// For error checking
DYNAMIC_ARRAY
m_glabel
;
// Goto labels
List
<
sp_label_t
>
m_label
;
// The label list
...
...
sql/sql_yacc.yy
View file @
d7ace789
...
...
@@ -611,6 +611,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CURSOR_SYM
%token ELSEIF_SYM
%token ITERATE_SYM
%token GOTO_SYM
%token LABEL_SYM
%token LEAVE_SYM
%token LOOP_SYM
%token REPEAT_SYM
...
...
@@ -1180,13 +1182,16 @@ create:
sp_proc_stmt
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
lex->sphead->init_strings(YYTHD, lex, $3);
if (sp->check_backpatch(YYTHD))
YYABORT;
sp->init_strings(YYTHD, lex, $3);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* Restore flag if it was cleared above */
if (
lex->sphead
->m_old_cmq)
if (
sp
->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
lex->sphead
->restore_thd_mem_root(YYTHD);
sp
->restore_thd_mem_root(YYTHD);
}
| CREATE or_replace algorithm VIEW_SYM table_ident
{
...
...
@@ -1286,6 +1291,8 @@ create_function_tail:
LEX *lex= Lex;
sp_head *sp= lex->sphead;
if (sp->check_backpatch(YYTHD))
YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(YYTHD, lex, lex->spname);
/* Restore flag if it was cleared above */
...
...
@@ -1816,7 +1823,8 @@ sp_proc_stmt:
{
LEX *lex= Lex;
sp_head *sp = lex->sphead;
sp_label_t *lab= lex->spcont->find_label($2.str);
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($2.str);
if (! lab)
{
...
...
@@ -1825,8 +1833,20 @@ sp_proc_stmt:
}
else
{
sp_instr_jump *i= new sp_instr_jump(sp->instructions());
uint ip= sp->instructions();
sp_scope_t sdiff;
sp_instr_jump *i;
sp_instr_hpop *ih;
sp_instr_cpop *ic;
ctx->diff_scopes(0, &sdiff);
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
sp->push_backpatch(ih, lab);
sp->add_instr(ih);
ic= new sp_instr_cpop(ip++, sdiff.curs);
sp->push_backpatch(ic, lab);
sp->add_instr(ic);
i= new sp_instr_jump(ip);
sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i);
}
...
...
@@ -1834,19 +1854,101 @@ sp_proc_stmt:
| ITERATE_SYM IDENT
{
LEX *lex= Lex;
sp_label_t *lab= lex->spcont->find_label($2.str);
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($2.str);
if (! lab || lab->
isbegin
)
if (! lab || lab->
type != SP_LAB_ITER
)
{
net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE", $2.str);
YYABORT;
}
else
{
sp_instr_jump *i;
uint ip= sp->instructions();
sp_scope_t sdiff;
ctx->diff_scopes(lab->scopes, &sdiff);
if (sdiff.hndlrs)
sp->add_instr(new sp_instr_hpop(ip++, sdiff.hndlrs));
if (sdiff.curs)
sp->add_instr(new sp_instr_cpop(ip++, sdiff.curs));
i= new sp_instr_jump(ip, lab->ip); /* Jump back */
sp->add_instr(i);
}
}
| LABEL_SYM IDENT
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($2.str);
if (! lab)
lab= ctx->find_glabel($2.str);
if (lab)
{
net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $2.str);
YYABORT;
}
else
{
lab= ctx->push_glabel($2.str, sp->instructions());
lab->type= SP_LAB_GOTO;
lab->scopes= ctx->scopes();
sp->backpatch(lab);
}
}
| GOTO_SYM IDENT
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
uint ip= lex->sphead->instructions();
sp_instr_jump *i= new sp_instr_jump(ip, lab->ip); /* Jump back */
sp_label_t *lab= ctx->find_label($2.str);
sp_scope_t sdiff;
sp_instr_jump *i;
sp_instr_hpop *ih;
sp_instr_cpop *ic;
lex->sphead->add_instr(i);
if (! lab)
lab= ctx->find_glabel($2.str);
if (! lab)
{
lab= (sp_label_t *)YYTHD->alloc(sizeof(sp_label_t));
lab->name= $2.str;
lab->ip= 0;
lab->type= SP_LAB_REF;
lab->scopes= 0;
ctx->diff_scopes(0, &sdiff);
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
sp->push_backpatch(ih, lab);
sp->add_instr(ih);
ic= new sp_instr_cpop(ip++, sdiff.curs);
sp->add_instr(ic);
sp->push_backpatch(ic, lab);
i= new sp_instr_jump(ip);
sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i);
}
else
{
ctx->diff_scopes(lab->scopes, &sdiff);
if (sdiff.hndlrs)
{
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
sp->add_instr(ih);
}
if (sdiff.curs)
{
ic= new sp_instr_cpop(ip++, sdiff.curs);
sp->add_instr(ic);
}
i= new sp_instr_jump(ip, lab->ip); /* Jump back */
sp->add_instr(i);
}
}
| OPEN_SYM ident
...
...
@@ -2041,7 +2143,8 @@ sp_labeled_control:
IDENT ':'
{
LEX *lex= Lex;
sp_label_t *lab= lex->spcont->find_label($1.str);
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($1.str);
if (lab)
{
...
...
@@ -2050,8 +2153,10 @@ sp_labeled_control:
}
else
{
lex->spcont->push_label($1.str,
l
ab= l
ex->spcont->push_label($1.str,
lex->sphead->instructions());
lab->type= SP_LAB_ITER;
lab->scopes= ctx->scopes();
}
}
sp_unlabeled_control sp_opt_label
...
...
@@ -2088,27 +2193,33 @@ sp_unlabeled_control:
LEX *lex= Lex;
sp_label_t *lab= lex->spcont->last_label();
lab->
isbegin= TRUE
;
lab->
type= SP_LAB_BEGIN
;
/* Scope duplicate checking */
lex->spcont->push_scope();
}
sp_decls
{
Lex->spcont->push_handlers($3.hndlrs);
}
sp_proc_stmts
END
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
sp_scope_t scope;
sp->backpatch(ctx->last_label()); /* We always ha
s
a label */
sp->backpatch(ctx->last_label()); /* We always ha
ve
a label */
ctx->pop_pvar($3.vars);
ctx->pop_cond($3.conds);
ctx->pop_handlers($3.hndlrs);
ctx->pop_cursor($3.curs);
if ($3.hndlrs)
sp->add_instr(new sp_instr_hpop(sp->instructions(),$3.hndlrs));
sp->add_instr(new sp_instr_hpop(sp->instructions(),
$3.hndlrs));
if ($3.curs)
sp->add_instr(new sp_instr_cpop(sp->instructions(), $3.curs));
ctx->pop_scope();
ctx->pop_scope(&scope);
ctx->pop_glabel(scope.glab);
}
| LOOP_SYM
sp_proc_stmts END LOOP_SYM
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment