Skip to content

Commit 91bb8f2

Browse files
committed
修复tuple操作中存在栈数据时会导致程序崩溃
支持在windows下编译
1 parent eb02a75 commit 91bb8f2

File tree

9 files changed

+260
-11
lines changed

9 files changed

+260
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ qrc_*.cpp
3232
ui_*.h
3333
Makefile*
3434
*build-*
35+
build
3536

3637
# QtCreator
3738

3rdparty/FlexLexer.h

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
// -*-C++-*-
2+
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
3+
// by flex
4+
5+
// Copyright (c) 1993 The Regents of the University of California.
6+
// All rights reserved.
7+
//
8+
// This code is derived from software contributed to Berkeley by
9+
// Kent Williams and Tom Epperly.
10+
//
11+
// Redistribution and use in source and binary forms, with or without
12+
// modification, are permitted provided that the following conditions
13+
// are met:
14+
15+
// 1. Redistributions of source code must retain the above copyright
16+
// notice, this list of conditions and the following disclaimer.
17+
// 2. Redistributions in binary form must reproduce the above copyright
18+
// notice, this list of conditions and the following disclaimer in the
19+
// documentation and/or other materials provided with the distribution.
20+
21+
// Neither the name of the University nor the names of its contributors
22+
// may be used to endorse or promote products derived from this software
23+
// without specific prior written permission.
24+
25+
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
26+
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
27+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28+
// PURPOSE.
29+
30+
// This file defines FlexLexer, an abstract class which specifies the
31+
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
32+
// which defines a particular lexer class.
33+
//
34+
// If you want to create multiple lexer classes, you use the -P flag
35+
// to rename each yyFlexLexer to some other xxFlexLexer. You then
36+
// include <FlexLexer.h> in your other sources once per lexer class:
37+
//
38+
// #undef yyFlexLexer
39+
// #define yyFlexLexer xxFlexLexer
40+
// #include <FlexLexer.h>
41+
//
42+
// #undef yyFlexLexer
43+
// #define yyFlexLexer zzFlexLexer
44+
// #include <FlexLexer.h>
45+
// ...
46+
47+
#ifndef __FLEX_LEXER_H
48+
// Never included before - need to define base class.
49+
#define __FLEX_LEXER_H
50+
51+
#include <iostream>
52+
53+
extern "C++" {
54+
55+
struct yy_buffer_state;
56+
typedef int yy_state_type;
57+
58+
class FlexLexer
59+
{
60+
public:
61+
virtual ~FlexLexer() { }
62+
63+
const char* YYText() const { return yytext; }
64+
int YYLeng() const { return yyleng; }
65+
66+
virtual void
67+
yy_switch_to_buffer( yy_buffer_state* new_buffer ) = 0;
68+
virtual yy_buffer_state* yy_create_buffer( std::istream* s, int size ) = 0;
69+
virtual yy_buffer_state* yy_create_buffer( std::istream& s, int size ) = 0;
70+
virtual void yy_delete_buffer( yy_buffer_state* b ) = 0;
71+
virtual void yyrestart( std::istream* s ) = 0;
72+
virtual void yyrestart( std::istream& s ) = 0;
73+
74+
virtual int yylex() = 0;
75+
76+
// Call yylex with new input/output sources.
77+
int yylex( std::istream& new_in, std::ostream& new_out )
78+
{
79+
switch_streams( new_in, new_out );
80+
return yylex();
81+
}
82+
83+
int yylex( std::istream* new_in, std::ostream* new_out = 0)
84+
{
85+
switch_streams( new_in, new_out );
86+
return yylex();
87+
}
88+
89+
// Switch to new input/output streams. A nil stream pointer
90+
// indicates "keep the current one".
91+
virtual void switch_streams( std::istream* new_in,
92+
std::ostream* new_out ) = 0;
93+
virtual void switch_streams( std::istream& new_in,
94+
std::ostream& new_out ) = 0;
95+
96+
int lineno() const { return yylineno; }
97+
98+
int debug() const { return yy_flex_debug; }
99+
void set_debug( int flag ) { yy_flex_debug = flag; }
100+
101+
protected:
102+
char* yytext;
103+
int yyleng;
104+
int yylineno; // only maintained if you use %option yylineno
105+
int yy_flex_debug; // only has effect with -d or "%option debug"
106+
};
107+
108+
}
109+
#endif // FLEXLEXER_H
110+
111+
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
112+
// Either this is the first time through (yyFlexLexerOnce not defined),
113+
// or this is a repeated include to define a different flavor of
114+
// yyFlexLexer, as discussed in the flex manual.
115+
# define yyFlexLexerOnce
116+
117+
extern "C++" {
118+
119+
class yyFlexLexer : public FlexLexer {
120+
public:
121+
// arg_yyin and arg_yyout default to the cin and cout, but we
122+
// only make that assignment when initializing in yylex().
123+
yyFlexLexer( std::istream& arg_yyin, std::ostream& arg_yyout );
124+
yyFlexLexer( std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0 );
125+
private:
126+
void ctor_common();
127+
128+
public:
129+
130+
virtual ~yyFlexLexer();
131+
132+
void yy_switch_to_buffer( yy_buffer_state* new_buffer );
133+
yy_buffer_state* yy_create_buffer( std::istream* s, int size );
134+
yy_buffer_state* yy_create_buffer( std::istream& s, int size );
135+
void yy_delete_buffer( yy_buffer_state* b );
136+
void yyrestart( std::istream* s );
137+
void yyrestart( std::istream& s );
138+
139+
void yypush_buffer_state( yy_buffer_state* new_buffer );
140+
void yypop_buffer_state();
141+
142+
virtual int yylex();
143+
virtual void switch_streams( std::istream& new_in, std::ostream& new_out );
144+
virtual void switch_streams( std::istream* new_in = 0, std::ostream* new_out = 0 );
145+
virtual int yywrap();
146+
147+
protected:
148+
virtual int LexerInput( char* buf, int max_size );
149+
virtual void LexerOutput( const char* buf, int size );
150+
virtual void LexerError( const char* msg );
151+
152+
void yyunput( int c, char* buf_ptr );
153+
int yyinput();
154+
155+
void yy_load_buffer_state();
156+
void yy_init_buffer( yy_buffer_state* b, std::istream& s );
157+
void yy_flush_buffer( yy_buffer_state* b );
158+
159+
int yy_start_stack_ptr;
160+
int yy_start_stack_depth;
161+
int* yy_start_stack;
162+
163+
void yy_push_state( int new_state );
164+
void yy_pop_state();
165+
int yy_top_state();
166+
167+
yy_state_type yy_get_previous_state();
168+
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
169+
int yy_get_next_buffer();
170+
171+
std::istream yyin; // input source for default LexerInput
172+
std::ostream yyout; // output sink for default LexerOutput
173+
174+
// yy_hold_char holds the character lost when yytext is formed.
175+
char yy_hold_char;
176+
177+
// Number of characters read into yy_ch_buf.
178+
int yy_n_chars;
179+
180+
// Points to current character in buffer.
181+
char* yy_c_buf_p;
182+
183+
int yy_init; // whether we need to initialize
184+
int yy_start; // start state number
185+
186+
// Flag which is used to allow yywrap()'s to do buffer switches
187+
// instead of setting up a fresh yyin. A bit of a hack ...
188+
int yy_did_buffer_switch_on_eof;
189+
190+
191+
size_t yy_buffer_stack_top; /**< index of top of stack. */
192+
size_t yy_buffer_stack_max; /**< capacity of stack. */
193+
yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
194+
void yyensure_buffer_stack(void);
195+
196+
// The following are not always needed, but may be depending
197+
// on use of certain flex features (like REJECT or yymore()).
198+
199+
yy_state_type yy_last_accepting_state;
200+
char* yy_last_accepting_cpos;
201+
202+
yy_state_type* yy_state_buf;
203+
yy_state_type* yy_state_ptr;
204+
205+
char* yy_full_match;
206+
int* yy_full_state;
207+
int yy_full_lp;
208+
209+
int yy_lp;
210+
int yy_looking_for_trail_begin;
211+
212+
int yy_more_flag;
213+
int yy_more_len;
214+
int yy_more_offset;
215+
int yy_prev_more_offset;
216+
};
217+
218+
}
219+
220+
#endif // yyFlexLexer || ! yyFlexLexerOnce

common/zcode.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,14 @@ ZVariant ZCode::exec(const QList<ZCode *> &codeList)
354354
tuple.reserve(argsCount);
355355

356356
for(int i = 0; i< argsCount; ++i) {
357-
tuple.insert(0, virtualStack.pop());
357+
// 栈中的数据都是保存在了temporaryList中
358+
// 此函数返回时其中的数据就全部被销毁了,Tuple
359+
// 中存储的是指针,指针指向的是temporaryList中的数据
360+
// 此exec可能是被其他函数调用的,因此Tuple中
361+
// 存储的可能是栈变量,函数执行结束后被其他作用
362+
// 域调用则访问到了无效指针,因此这里要new一个
363+
// 新的ZVariant
364+
tuple.prepend(new ZVariant(*virtualStack.pop()));
358365
}
359366

360367
temporaryList << std::move(tuple);

common/zglobal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#define zWarning qWarning().noquote() << "[Warning]:"
1212
#define zPrint qDebug().noquote()
1313
#define zStandardPrint std::cout
14-
#define zExit(code) quick_exit(code)
14+
#define zExit(code) exit(code)
1515
#define zErrorQuit zExit(-1)
1616
#define zQuit zExit(0)
1717

common/zvariant.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ ZVariant::ZVariant(const ZVariant &other)
4848

4949
ZVariant::ZVariant(ZVariant &&other)
5050
{
51-
qSwap(m_data, other.m_data);
51+
m_data.swap(other.m_data);
5252
}
5353

5454
ZVariant::ZVariant(const QString &val)
@@ -681,6 +681,7 @@ ZVariant operator ~(const ZVariant &var)
681681

682682
Z_END_NAMESPACE
683683

684+
QT_BEGIN_NAMESPACE
684685
QDebug operator<<(QDebug deg, const ZVariant &var)
685686
{
686687
deg.nospace() << "Variant(" << var.typeName() << ", ";
@@ -713,7 +714,6 @@ QDebug operator<<(QDebug deg, const ZVariant &var)
713714
return deg;
714715
}
715716

716-
QT_BEGIN_NAMESPACE
717717
uint qHash(const ZVariant &val, uint seed)
718718
{
719719
switch (val.type()) {

common/zvariant.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,19 @@ class ZVariant
9999

100100
VariantData *data = const_cast<VariantData*>(this->m_data.constData());
101101

102-
data->variant = other.m_data->variant;
102+
if (other.type() == Tuple) {
103+
// 元组类型由于存储的是指针,因此也要深度复制
104+
ZTuple tuple;
105+
106+
for (const ZVariant *i : other.toTuple()) {
107+
tuple << new ZVariant(*i);
108+
}
109+
110+
data->variant = QVariant::fromValue(tuple);
111+
} else {
112+
data->variant = other.m_data->variant;
113+
}
114+
103115
data->type = other.m_data->type;
104116
}
105117

@@ -130,10 +142,10 @@ class ZVariant
130142
int min = qMin(other_group.count(), this_group.count());
131143

132144
for(int i = 0; i < min; ++i) {
133-
qSwap(this_group[i]->m_data, other_group[i]->m_data);
145+
this_group[i]->m_data.swap(other_group[i]->m_data);
134146
}
135147
} else {
136-
qSwap(m_data, other.m_data);
148+
m_data.swap(other.m_data);
137149
}
138150

139151
return *this;
@@ -215,6 +227,13 @@ class ZVariant
215227
class VariantData : public QSharedData
216228
{
217229
public:
230+
~VariantData() {
231+
if (type == Tuple) {
232+
// 销毁列表中的数据
233+
qDeleteAll(qvariant_cast<ZTuple>(variant));
234+
}
235+
}
236+
218237
QVariant variant;
219238
ZVariant::Type type;
220239
};
@@ -353,7 +372,7 @@ class ZSharedVariant : public ZVariant, public QSharedData
353372
Z_END_NAMESPACE
354373

355374
QT_BEGIN_NAMESPACE
356-
Q_CORE_EXPORT QDebug operator<<(QDebug deg, const ZVariant &var);
375+
QDebug operator<<(QDebug deg, const ZVariant &var);
357376
QT_END_NAMESPACE
358377

359378
Q_DECLARE_METATYPE(ZVariant)

lexical/lexical.pri

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ SOURCES += $$PWD/lex.yy.cpp
22

33
OTHER_FILES += $$PWD/zScript.ll
44

5-
system(flex -+ -o lex.yy.cpp $$PWD/zScript.ll)
5+
win*: INCLUDEPATH += $$PWD/../3rdparty
6+
else: system(flex -+ -o lex.yy.cpp $$PWD/zScript.ll)
67

78
INCLUDEPATH += $$PWD

syntax/syntax.pri

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ SOURCES += \
66

77
OTHER_FILES += $$PWD/zScript.yy
88

9-
system(bison -d -v -L c++ -o zScript.tab.cpp $$PWD/zScript.yy)
9+
win*: INCLUDEPATH += $$PWD/../3rdparty
10+
else: system(bison -d -v -L c++ -o zScript.tab.cpp $$PWD/zScript.yy)
1011

1112
INCLUDEPATH += $$PWD

syntax/zScript.yy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ void yy::parser::error(const location_type& loc, const std::string& msg)
999999
std::cerr << "from " << loc.begin.line << " line " << loc.begin.column << " column, "
10001000
<< "to " << loc.end.line << " line " << loc.end.column << " column, " << msg << std::endl;
10011001

1002-
quick_exit(-1);
1002+
exit(-1);
10031003
}
10041004

10051005
int yylex(yy::parser::semantic_type *lval, yy::parser::location_type *location)

0 commit comments

Comments
 (0)