summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--mrbgems/mruby-compiler/core/parse.y103
-rw-r--r--mrbgems/mruby-random/src/mt19937ar.c31
-rw-r--r--mrbgems/mruby-random/src/mt19937ar.h31
-rw-r--r--mrbgems/mruby-string-ext/src/string.c2
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb4
-rw-r--r--mrblib/00class.rb26
-rw-r--r--mrblib/10error.rb (renamed from mrblib/error.rb)0
-rw-r--r--mrblib/class.rb11
-rw-r--r--src/class.c38
-rw-r--r--test/t/exception.rb6
-rwxr-xr-xtest/t/lang.rb74
12 files changed, 224 insertions, 117 deletions
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index 93a18f442..000000000
--- a/ChangeLog
+++ /dev/null
@@ -1,15 +0,0 @@
-Thu Apl 19 17:25:18 2012 Yukihiro Matsumoto <[email protected]>
-
- * first release version 1.0.0 released.
-
-Local variables:
-add-log-time-format: (lambda ()
- (let* ((time (current-time))
- (system-time-locale "C")
- (diff (+ (cadr time) 32400))
- (lo (% diff 65536))
- (hi (+ (car time) (/ diff 65536))))
- (format-time-string "%a %b %e %H:%M:%S %Y" (list hi lo) t)))
-indent-tabs-mode: t
-tab-width: 8
-end:
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 1ddf483a8..51a08a489 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -310,6 +310,12 @@ new_rescue(parser_state *p, node *body, node *resq, node *els)
return list4((node*)NODE_RESCUE, body, resq, els);
}
+static node*
+new_mod_rescue(parser_state *p, node *body, node *resq)
+{
+ return new_rescue(p, body, list1(list3(0, 0, resq)), 0);
+}
+
/* (:ensure body ensure) */
static node*
new_ensure(parser_state *p, node *a, node *b)
@@ -1091,12 +1097,12 @@ heredoc_end(parser_state *p)
%type <nd> literal numeric cpath symbol
%type <nd> top_compstmt top_stmts top_stmt
%type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
-%type <nd> expr_value arg_value primary_value
+%type <nd> expr_value arg_value arg_rhs primary_value
%type <nd> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
%type <nd> args call_args opt_call_args
%type <nd> paren_args opt_paren_args variable
%type <nd> command_args aref_args opt_block_arg block_arg var_ref var_lhs
-%type <nd> command_asgn mrhs superclass block_call block_command
+%type <nd> command_asgn command_rhs mrhs superclass block_call block_command
%type <nd> f_block_optarg f_block_opt
%type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
%type <nd> assoc_list assocs assoc undef_list backref for_var
@@ -1300,7 +1306,7 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
}
| stmt modifier_rescue stmt
{
- $$ = new_rescue(p, $1, list1(list3(0, 0, $3)), 0);
+ $$ = new_mod_rescue(p, $1, $3);
}
| keyword_END '{' compstmt '}'
{
@@ -1312,19 +1318,38 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
{
$$ = new_masgn(p, $1, $3);
}
- | var_lhs tOP_ASGN command_call
+ | lhs '=' mrhs
+ {
+ $$ = new_asgn(p, $1, new_array(p, $3));
+ }
+ | mlhs '=' arg_value
+ {
+ $$ = new_masgn(p, $1, $3);
+ }
+ | mlhs '=' mrhs
+ {
+ $$ = new_masgn(p, $1, new_array(p, $3));
+ }
+ | expr
+ ;
+
+command_asgn : lhs '=' command_rhs
+ {
+ $$ = new_asgn(p, $1, $3);
+ }
+ | var_lhs tOP_ASGN command_rhs
{
$$ = new_op_asgn(p, $1, $2, $3);
}
- | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
+ | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
}
- | primary_value call_op tIDENTIFIER tOP_ASGN command_call
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
}
- | primary_value call_op tCONSTANT tOP_ASGN command_call
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
}
@@ -1333,38 +1358,23 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
yyerror(p, "constant re-assignment");
$$ = 0;
}
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5);
}
- | backref tOP_ASGN command_call
+ | backref tOP_ASGN command_rhs
{
backref_error(p, $1);
$$ = new_begin(p, 0);
}
- | lhs '=' mrhs
- {
- $$ = new_asgn(p, $1, new_array(p, $3));
- }
- | mlhs '=' arg_value
- {
- $$ = new_masgn(p, $1, $3);
- }
- | mlhs '=' mrhs
- {
- $$ = new_masgn(p, $1, new_array(p, $3));
- }
- | expr
- ;
+ ;
-command_asgn : lhs '=' command_call
- {
- $$ = new_asgn(p, $1, $3);
- }
- | lhs '=' command_asgn
+command_rhs : command_call %prec tOP_ASGN
+ | command_call modifier_rescue stmt
{
- $$ = new_asgn(p, $1, $3);
+ $$ = new_mod_rescue(p, $1, $3);
}
+ | command_asgn
;
@@ -1724,49 +1734,41 @@ reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
| keyword_while | keyword_until
;
-arg : lhs '=' arg
+arg : lhs '=' arg_rhs
{
$$ = new_asgn(p, $1, $3);
}
- | lhs '=' arg modifier_rescue arg
- {
- $$ = new_asgn(p, $1, new_rescue(p, $3, list1(list3(0, 0, $5)), 0));
- }
- | var_lhs tOP_ASGN arg
+ | var_lhs tOP_ASGN arg_rhs
{
$$ = new_op_asgn(p, $1, $2, $3);
}
- | var_lhs tOP_ASGN arg modifier_rescue arg
- {
- $$ = new_op_asgn(p, $1, $2, new_rescue(p, $3, list1(list3(0, 0, $5)), 0));
- }
- | primary_value '[' opt_call_args rbracket tOP_ASGN arg
+ | primary_value '[' opt_call_args rbracket tOP_ASGN arg_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
}
- | primary_value call_op tIDENTIFIER tOP_ASGN arg
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
}
- | primary_value call_op tCONSTANT tOP_ASGN arg
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
}
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
{
$$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5);
}
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
{
yyerror(p, "constant re-assignment");
$$ = new_begin(p, 0);
}
- | tCOLON3 tCONSTANT tOP_ASGN arg
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
{
yyerror(p, "constant re-assignment");
$$ = new_begin(p, 0);
}
- | backref tOP_ASGN arg
+ | backref tOP_ASGN arg_rhs
{
backref_error(p, $1);
$$ = new_begin(p, 0);
@@ -1929,6 +1931,13 @@ aref_args : none
}
;
+arg_rhs : arg %prec tOP_ASGN
+ | arg modifier_rescue arg
+ {
+ $$ = new_mod_rescue(p, $1, $3);
+ }
+ ;
+
paren_args : '(' opt_call_args rparen
{
$$ = $2;
@@ -2081,7 +2090,7 @@ primary : literal
$<stack>$ = p->cmdarg_stack;
p->cmdarg_stack = 0;
}
- expr {p->lstate = EXPR_ENDARG;} rparen
+ stmt {p->lstate = EXPR_ENDARG;} rparen
{
p->cmdarg_stack = $<stack>2;
$$ = $3;
diff --git a/mrbgems/mruby-random/src/mt19937ar.c b/mrbgems/mruby-random/src/mt19937ar.c
index 4013ad30b..bee06b574 100644
--- a/mrbgems/mruby-random/src/mt19937ar.c
+++ b/mrbgems/mruby-random/src/mt19937ar.c
@@ -1,7 +1,36 @@
/*
** mt19937ar.c - MT Random functions
**
-** See Copyright Notice in mruby.h
+** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura,
+** All rights reserved.
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+**
+** Any feedback is very welcome.
+** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+**
+** This version is modified by mruby developers. If you see any problem,
+** contact us first at https://github.com/mruby/mruby/issues
*/
#include <mruby.h>
diff --git a/mrbgems/mruby-random/src/mt19937ar.h b/mrbgems/mruby-random/src/mt19937ar.h
index 59027c624..31e5d19ed 100644
--- a/mrbgems/mruby-random/src/mt19937ar.h
+++ b/mrbgems/mruby-random/src/mt19937ar.h
@@ -1,7 +1,36 @@
/*
** mt19937ar.h - MT Random functions
**
-** See Copyright Notice in mruby.h
+** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura,
+** All rights reserved.
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+**
+** Any feedback is very welcome.
+** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+**
+** This version is modified by mruby developers. If you see any problem,
+** contact us first at https://github.com/mruby/mruby/issues
*/
#define N 624
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index c2ee1fc23..2a52d53b3 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -529,7 +529,7 @@ mrb_str_ord(mrb_state* mrb, mrb_value str)
{
if (RSTRING_LEN(str) == 0)
mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string");
- return mrb_fixnum_value(RSTRING_PTR(str)[0]);
+ return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[0]);
}
#endif
diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb
index aa3e8a192..a5d55a7ee 100644
--- a/mrbgems/mruby-string-ext/test/string.rb
+++ b/mrbgems/mruby-string-ext/test/string.rb
@@ -497,6 +497,10 @@ end
assert('String#ord') do
got = "hello!".split('').map {|x| x.ord}
expect = [104, 101, 108, 108, 111, 33]
+ unless UTF8STRING
+ got << "\xff".ord
+ expect << 0xff
+ end
assert_equal expect, got
end
diff --git a/mrblib/00class.rb b/mrblib/00class.rb
new file mode 100644
index 000000000..f3762e8d0
--- /dev/null
+++ b/mrblib/00class.rb
@@ -0,0 +1,26 @@
+class Module
+ # 15.2.2.4.12
+ def attr_accessor(*names)
+ attr_reader(*names)
+ attr_writer(*names)
+ end
+ # 15.2.2.4.11
+ def attr(name)
+ attr_reader(name)
+ end
+
+ # 15.2.2.4.27
+ def include(*args)
+ args.reverse.each do |m|
+ m.append_features(self)
+ m.included(self)
+ end
+ end
+
+ def prepend(*args)
+ args.reverse.each do |m|
+ m.prepend_features(self)
+ m.prepended(self)
+ end
+ end
+end
diff --git a/mrblib/error.rb b/mrblib/10error.rb
index 2674af7a2..2674af7a2 100644
--- a/mrblib/error.rb
+++ b/mrblib/10error.rb
diff --git a/mrblib/class.rb b/mrblib/class.rb
deleted file mode 100644
index 39e0d5091..000000000
--- a/mrblib/class.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class Module
- # 15.2.2.4.12
- def attr_accessor(*names)
- attr_reader(*names)
- attr_writer(*names)
- end
- # 15.2.2.4.11
- def attr(name)
- attr_reader(name)
- end
-end
diff --git a/src/class.c b/src/class.c
index 0f72c7753..47a6c846b 100644
--- a/src/class.c
+++ b/src/class.c
@@ -948,24 +948,6 @@ mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod)
}
static mrb_value
-mrb_mod_prepend(mrb_state *mrb, mrb_value klass)
-{
- mrb_value *argv;
- mrb_int argc, i;
-
- mrb_get_args(mrb, "*", &argv, &argc);
- for (i=0; i<argc; i++) {
- mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
- }
- while (argc--) {
- mrb_funcall(mrb, argv[argc], "prepend_features", 1, klass);
- mrb_funcall(mrb, argv[argc], "prepended", 1, klass);
- }
-
- return klass;
-}
-
-static mrb_value
mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
{
mrb_value klass;
@@ -976,24 +958,6 @@ mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
return mod;
}
-static mrb_value
-mrb_mod_include(mrb_state *mrb, mrb_value klass)
-{
- mrb_value *argv;
- mrb_int argc, i;
-
- mrb_get_args(mrb, "*", &argv, &argc);
- for (i=0; i<argc; i++) {
- mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
- }
- while (argc--) {
- mrb_funcall(mrb, argv[argc], "append_features", 1, klass);
- mrb_funcall(mrb, argv[argc], "included", 1, klass);
- }
-
- return klass;
-}
-
/* 15.2.2.4.28 */
/*
* call-seq:
@@ -2247,10 +2211,8 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */
mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
- mrb_define_method(mrb, mod, "prepend", mrb_mod_prepend, MRB_ARGS_ANY());
mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1));
mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, mod, "include", mrb_mod_include, MRB_ARGS_ANY()); /* 15.2.2.4.27 */
mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */
mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */
diff --git a/test/t/exception.rb b/test/t/exception.rb
index 742f4a044..839250ea8 100644
--- a/test/t/exception.rb
+++ b/test/t/exception.rb
@@ -373,7 +373,7 @@ assert('Raise in ensure') do
end
end
-def backtrace_avaialble?
+def backtrace_available?
begin
raise "XXX"
rescue => exception
@@ -382,7 +382,7 @@ def backtrace_avaialble?
end
assert('GC in rescue') do
- skip "backtrace isn't avaialble" unless backtrace_avaialble?
+ skip "backtrace isn't available" unless backtrace_available?
line = nil
begin
@@ -401,7 +401,7 @@ assert('GC in rescue') do
end
assert('Method call in rescue') do
- skip "backtrace isn't avaialble" unless backtrace_avaialble?
+ skip "backtrace isn't available" unless backtrace_available?
line = nil
begin
diff --git a/test/t/lang.rb b/test/t/lang.rb
new file mode 100755
index 000000000..57c375643
--- /dev/null
+++ b/test/t/lang.rb
@@ -0,0 +1,74 @@
+# The aim of these tests is to detect pitfall for optimized VM.
+
+# Test for or/and
+#
+# You may think instruction fusion(OP_EQ and OP_JMPIF) for avoiding
+# generate intermediate boolean value.
+# But and/or is pitfall for this fusioning.
+#
+# For example, the following mruby code:
+#
+# if i > 0 and i < 10 then
+#
+# compiles to the following byte code:
+#
+# 1 000 OP_LOADI R1 0 ; R1:i
+# 2 001 OP_MOVE R2 R1 ; R1:i
+# 2 002 OP_LOADI R3 0
+# 2 003 OP_GT R2 :> 1
+# 2 004 OP_JMPNOT R2 008
+# 2 005 OP_MOVE R2 R1 ; R1:i
+# 2 006 OP_LOADI R3 10
+# 2 007 OP_LT R2 :< 1
+# 2 008 OP_JMPNOT R2 (The address of end of then part)
+#
+# When the instruction fusion the OP_GT and OP_JMPNOT you fell into the pitfalls.
+# The deleted intermediate boolean value is used in OP_JMPNOT (address 008).
+
+assert('and', '11.2.3') do
+ a = 1
+ if a > 0 and a < 10 then
+ b = 1
+ else
+ b = 0
+ end
+ assert_equal 1, b
+
+ if a < 0 and a < 10 then
+ b = 1
+ else
+ b = 0
+ end
+ assert_equal 0, b
+
+ if a < 0 and a > 10 then
+ b = 1
+ else
+ b = 0
+ end
+ assert_equal 0, b
+end
+
+assert('or','11.2.4') do
+ a = 1
+ if a > 0 or a < 10 then
+ b = 1
+ else
+ b = 0
+ end
+ assert_equal 1, b
+
+ if a < 0 or a < 10 then
+ b = 1
+ else
+ b = 0
+ end
+ assert_equal 1, b
+
+ if a < 0 or a > 10 then
+ b = 1
+ else
+ b = 0
+ end
+ assert_equal 0, b
+end