Ignore:
Timestamp:
Jul 9, 2020, 8:51:43 AM (4 years ago)
Author:
coas-nagasima
Message:

mrubyを2.1.1に更新

Location:
EcnlProtoTool/trunk/mruby-2.1.1
Files:
149 added
19 deleted
222 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-2.1.1/.cproject

    r426 r439  
    4949                                                        <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.1907336908" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
    5050                                                        <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.194370869" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
    51                                                         <builder buildPath="${workspace_loc:/mruby-1.3.0}" id="com.renesas.cdt.managedbuild.gcc.rz.builder.1751464165" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="GCC for Renesas Builder" superClass="com.renesas.cdt.managedbuild.gcc.rz.builder"/>
     51                                                        <builder buildPath="${workspace_loc:/mruby-2.1.1}" id="com.renesas.cdt.managedbuild.gcc.rz.builder.1751464165" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="GCC for Renesas Builder" superClass="com.renesas.cdt.managedbuild.gcc.rz.builder"/>
    5252                                                        <tool id="com.renesas.cdt.managedbuild.gcc.rz.tool.assembler.322468629" name="Cross ARM GNU Assembler" superClass="com.renesas.cdt.managedbuild.gcc.rz.tool.assembler">
    5353                                                                <option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1448772766" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
  • EcnlProtoTool/trunk/mruby-2.1.1/.gitignore

    r331 r439  
    1 # /
     1*.lock
    22*.bak
     3*.bc
    34*.d
     5*.i
    46*.o
    5 /benchmark/**/*.dat
    6 /benchmark/*.pdf
    7 /benchmark/*.png
    87*.orig
    98*.pdb
    109*.rej
     10*.s
    1111*.sav
    1212*.swp
     
    1616.ccmalloc
    1717.svn
    18 /.git
     18.vscode
     19.yardoc
     20cscope.files
    1921cscope.out
    2022tags
    21 /src/y.tab.c
     23
     24/.git
    2225/bin
    2326/build
    2427/mruby-source-*.gem
    25 doc/api
    26 .yardoc
     28
     29/benchmark/**/*.dat
     30/benchmark/*.pdf
     31/benchmark/*.png
     32
     33/doc/api
     34/doc/capi
  • EcnlProtoTool/trunk/mruby-2.1.1/.gitlab-ci.yml

    r331 r439  
    1212    CXX: g++-4.7
    1313    LD: gcc-4.7
    14   script: "./minirake all test"
     14  script: rake --verbose all test
    1515Test gcc-4.7 32bit:
     16  stage: test
     17  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     18  variables:
     19    CC: gcc-4.7
     20    CXX: g++-4.7
     21    LD: gcc-4.7
     22    CFLAGS: "-m32 "
     23    LDFLAGS: "-m32"
     24  script: env; rake --verbose all test
     25Test gcc-4.7 32bit_utf8:
     26  stage: test
     27  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     28  variables:
     29    CC: gcc-4.7
     30    CXX: g++-4.7
     31    LD: gcc-4.7
     32    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     33    LDFLAGS: "-m32"
     34  script: env; rake --verbose all test
     35Test gcc-4.7 32bit_nan:
     36  stage: test
     37  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     38  variables:
     39    CC: gcc-4.7
     40    CXX: g++-4.7
     41    LD: gcc-4.7
     42    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     43    LDFLAGS: "-m32"
     44  script: env; rake --verbose all test
     45Test gcc-4.7 32bit_nan_utf8:
     46  stage: test
     47  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     48  variables:
     49    CC: gcc-4.7
     50    CXX: g++-4.7
     51    LD: gcc-4.7
     52    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     53    LDFLAGS: "-m32"
     54  script: env; rake --verbose all test
     55Test gcc-4.7 32bit_word:
    1656  stage: test
    1757  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    2262    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    2363    LDFLAGS: "-m32"
    24   script: env; ./minirake --verbose all test
    25 Test gcc-4.7 32bit_utf8:
     64  script: env; rake --verbose all test
     65Test gcc-4.7 32bit_word_utf8:
    2666  stage: test
    2767  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    3272    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    3373    LDFLAGS: "-m32"
    34   script: env; ./minirake --verbose all test
    35 Test gcc-4.7 32bit_nan:
    36   stage: test
    37   image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
    38   variables:
    39     CC: gcc-4.7
    40     CXX: g++-4.7
    41     LD: gcc-4.7
    42     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    43     LDFLAGS: "-m32"
    44   script: env; ./minirake --verbose all test
    45 Test gcc-4.7 32bit_nan_utf8:
    46   stage: test
    47   image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
    48   variables:
    49     CC: gcc-4.7
    50     CXX: g++-4.7
    51     LD: gcc-4.7
    52     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    53     LDFLAGS: "-m32"
    54   script: env; ./minirake --verbose all test
     74  script: env; rake --verbose all test
    5575Test gcc-4.7 32bit_int16:
    5676  stage: test
     
    6282    CFLAGS: "-m32 -DMRB_INT16=1"
    6383    LDFLAGS: "-m32"
    64   script: env; ./minirake --verbose all test
     84  script: env; rake --verbose all test
    6585Test gcc-4.7 32bit_int16_utf8:
    6686  stage: test
     
    7292    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    7393    LDFLAGS: "-m32"
    74   script: env; ./minirake --verbose all test
     94  script: env; rake --verbose all test
    7595Test gcc-4.7 32bit_int16_nan:
    7696  stage: test
     
    82102    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    83103    LDFLAGS: "-m32"
    84   script: env; ./minirake --verbose all test
     104  script: env; rake --verbose all test
    85105Test gcc-4.7 32bit_int16_nan_utf8:
    86106  stage: test
     
    92112    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    93113    LDFLAGS: "-m32"
    94   script: env; ./minirake --verbose all test
     114  script: env; rake --verbose all test
    95115Test gcc-4.7 32bit_int64:
    96116  stage: test
     
    102122    CFLAGS: "-m32 -DMRB_INT64=1"
    103123    LDFLAGS: "-m32"
    104   script: env; ./minirake --verbose all test
     124  script: env; rake --verbose all test
    105125Test gcc-4.7 32bit_int64_utf8:
    106126  stage: test
     
    112132    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    113133    LDFLAGS: "-m32"
    114   script: env; ./minirake --verbose all test
     134  script: env; rake --verbose all test
    115135Test gcc-4.7 32bit_float:
     136  stage: test
     137  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     138  variables:
     139    CC: gcc-4.7
     140    CXX: g++-4.7
     141    LD: gcc-4.7
     142    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     143    LDFLAGS: "-m32"
     144  script: env; rake --verbose all test
     145Test gcc-4.7 32bit_float_utf8:
     146  stage: test
     147  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     148  variables:
     149    CC: gcc-4.7
     150    CXX: g++-4.7
     151    LD: gcc-4.7
     152    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     153    LDFLAGS: "-m32"
     154  script: env; rake --verbose all test
     155Test gcc-4.7 32bit_float_word:
    116156  stage: test
    117157  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    122162    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    123163    LDFLAGS: "-m32"
    124   script: env; ./minirake --verbose all test
    125 Test gcc-4.7 32bit_float_utf8:
     164  script: env; rake --verbose all test
     165Test gcc-4.7 32bit_float_word_utf8:
    126166  stage: test
    127167  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    132172    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    133173    LDFLAGS: "-m32"
    134   script: env; ./minirake --verbose all test
     174  script: env; rake --verbose all test
    135175Test gcc-4.7 32bit_float_int16:
    136176  stage: test
     
    142182    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    143183    LDFLAGS: "-m32"
    144   script: env; ./minirake --verbose all test
     184  script: env; rake --verbose all test
    145185Test gcc-4.7 32bit_float_int16_utf8:
    146186  stage: test
     
    152192    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    153193    LDFLAGS: "-m32"
    154   script: env; ./minirake --verbose all test
     194  script: env; rake --verbose all test
    155195Test gcc-4.7 32bit_float_int64:
    156196  stage: test
     
    162202    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    163203    LDFLAGS: "-m32"
    164   script: env; ./minirake --verbose all test
     204  script: env; rake --verbose all test
    165205Test gcc-4.7 32bit_float_int64_utf8:
    166206  stage: test
     
    172212    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    173213    LDFLAGS: "-m32"
    174   script: env; ./minirake --verbose all test
     214  script: env; rake --verbose all test
    175215Test gcc-4.7 64bit:
     216  stage: test
     217  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     218  variables:
     219    CC: gcc-4.7
     220    CXX: g++-4.7
     221    LD: gcc-4.7
     222    CFLAGS: ''
     223    LDFLAGS: ''
     224  script: env; rake --verbose all test
     225Test gcc-4.7 64bit_utf8:
     226  stage: test
     227  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     228  variables:
     229    CC: gcc-4.7
     230    CXX: g++-4.7
     231    LD: gcc-4.7
     232    CFLAGS: "-DMRB_UTF8_STRING=1"
     233    LDFLAGS: ''
     234  script: env; rake --verbose all test
     235Test gcc-4.7 64bit_nan:
     236  stage: test
     237  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     238  variables:
     239    CC: gcc-4.7
     240    CXX: g++-4.7
     241    LD: gcc-4.7
     242    CFLAGS: "-DMRB_NAN_BOXING=1"
     243    LDFLAGS: ''
     244  script: env; rake --verbose all test
     245Test gcc-4.7 64bit_nan_utf8:
     246  stage: test
     247  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     248  variables:
     249    CC: gcc-4.7
     250    CXX: g++-4.7
     251    LD: gcc-4.7
     252    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     253    LDFLAGS: ''
     254  script: env; rake --verbose all test
     255Test gcc-4.7 64bit_word:
    176256  stage: test
    177257  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    182262    CFLAGS: "-DMRB_WORD_BOXING=1"
    183263    LDFLAGS: ''
    184   script: env; ./minirake --verbose all test
    185 Test gcc-4.7 64bit_utf8:
     264  script: env; rake --verbose all test
     265Test gcc-4.7 64bit_word_utf8:
    186266  stage: test
    187267  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    192272    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    193273    LDFLAGS: ''
    194   script: env; ./minirake --verbose all test
    195 Test gcc-4.7 64bit_nan:
    196   stage: test
    197   image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
    198   variables:
    199     CC: gcc-4.7
    200     CXX: g++-4.7
    201     LD: gcc-4.7
    202     CFLAGS: "-DMRB_NAN_BOXING=1"
    203     LDFLAGS: ''
    204   script: env; ./minirake --verbose all test
    205 Test gcc-4.7 64bit_nan_utf8:
    206   stage: test
    207   image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
    208   variables:
    209     CC: gcc-4.7
    210     CXX: g++-4.7
    211     LD: gcc-4.7
    212     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    213     LDFLAGS: ''
    214   script: env; ./minirake --verbose all test
     274  script: env; rake --verbose all test
    215275Test gcc-4.7 64bit_int16:
    216276  stage: test
     
    222282    CFLAGS: "-DMRB_INT16=1"
    223283    LDFLAGS: ''
    224   script: env; ./minirake --verbose all test
     284  script: env; rake --verbose all test
    225285Test gcc-4.7 64bit_int16_utf8:
    226286  stage: test
     
    232292    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    233293    LDFLAGS: ''
    234   script: env; ./minirake --verbose all test
     294  script: env; rake --verbose all test
    235295Test gcc-4.7 64bit_int16_nan:
    236296  stage: test
     
    242302    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    243303    LDFLAGS: ''
    244   script: env; ./minirake --verbose all test
     304  script: env; rake --verbose all test
    245305Test gcc-4.7 64bit_int16_nan_utf8:
    246306  stage: test
     
    252312    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    253313    LDFLAGS: ''
    254   script: env; ./minirake --verbose all test
     314  script: env; rake --verbose all test
    255315Test gcc-4.7 64bit_int64:
     316  stage: test
     317  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     318  variables:
     319    CC: gcc-4.7
     320    CXX: g++-4.7
     321    LD: gcc-4.7
     322    CFLAGS: "-DMRB_INT64=1"
     323    LDFLAGS: ''
     324  script: env; rake --verbose all test
     325Test gcc-4.7 64bit_int64_utf8:
     326  stage: test
     327  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     328  variables:
     329    CC: gcc-4.7
     330    CXX: g++-4.7
     331    LD: gcc-4.7
     332    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     333    LDFLAGS: ''
     334  script: env; rake --verbose all test
     335Test gcc-4.7 64bit_int64_word:
    256336  stage: test
    257337  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    262342    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    263343    LDFLAGS: ''
    264   script: env; ./minirake --verbose all test
    265 Test gcc-4.7 64bit_int64_utf8:
     344  script: env; rake --verbose all test
     345Test gcc-4.7 64bit_int64_word_utf8:
    266346  stage: test
    267347  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    272352    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    273353    LDFLAGS: ''
    274   script: env; ./minirake --verbose all test
     354  script: env; rake --verbose all test
    275355Test gcc-4.7 64bit_float:
     356  stage: test
     357  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     358  variables:
     359    CC: gcc-4.7
     360    CXX: g++-4.7
     361    LD: gcc-4.7
     362    CFLAGS: "-DMRB_USE_FLOAT=1"
     363    LDFLAGS: ''
     364  script: env; rake --verbose all test
     365Test gcc-4.7 64bit_float_utf8:
     366  stage: test
     367  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     368  variables:
     369    CC: gcc-4.7
     370    CXX: g++-4.7
     371    LD: gcc-4.7
     372    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     373    LDFLAGS: ''
     374  script: env; rake --verbose all test
     375Test gcc-4.7 64bit_float_word:
    276376  stage: test
    277377  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    282382    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    283383    LDFLAGS: ''
    284   script: env; ./minirake --verbose all test
    285 Test gcc-4.7 64bit_float_utf8:
     384  script: env; rake --verbose all test
     385Test gcc-4.7 64bit_float_word_utf8:
    286386  stage: test
    287387  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    292392    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    293393    LDFLAGS: ''
    294   script: env; ./minirake --verbose all test
     394  script: env; rake --verbose all test
    295395Test gcc-4.7 64bit_float_int16:
    296396  stage: test
     
    302402    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    303403    LDFLAGS: ''
    304   script: env; ./minirake --verbose all test
     404  script: env; rake --verbose all test
    305405Test gcc-4.7 64bit_float_int16_utf8:
    306406  stage: test
     
    312412    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    313413    LDFLAGS: ''
    314   script: env; ./minirake --verbose all test
     414  script: env; rake --verbose all test
    315415Test gcc-4.7 64bit_float_int64:
     416  stage: test
     417  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     418  variables:
     419    CC: gcc-4.7
     420    CXX: g++-4.7
     421    LD: gcc-4.7
     422    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     423    LDFLAGS: ''
     424  script: env; rake --verbose all test
     425Test gcc-4.7 64bit_float_int64_utf8:
     426  stage: test
     427  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     428  variables:
     429    CC: gcc-4.7
     430    CXX: g++-4.7
     431    LD: gcc-4.7
     432    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     433    LDFLAGS: ''
     434  script: env; rake --verbose all test
     435Test gcc-4.7 64bit_float_int64_word:
    316436  stage: test
    317437  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    322442    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    323443    LDFLAGS: ''
    324   script: env; ./minirake --verbose all test
    325 Test gcc-4.7 64bit_float_int64_utf8:
     444  script: env; rake --verbose all test
     445Test gcc-4.7 64bit_float_int64_word_utf8:
    326446  stage: test
    327447  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
     
    332452    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    333453    LDFLAGS: ''
    334   script: env; ./minirake --verbose all test
     454  script: env; rake --verbose all test
    335455Test gcc-4.8 32bit:
     456  stage: test
     457  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     458  variables:
     459    CC: gcc-4.8
     460    CXX: g++-4.8
     461    LD: gcc-4.8
     462    CFLAGS: "-m32 "
     463    LDFLAGS: "-m32"
     464  script: env; rake --verbose all test
     465Test gcc-4.8 32bit_utf8:
     466  stage: test
     467  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     468  variables:
     469    CC: gcc-4.8
     470    CXX: g++-4.8
     471    LD: gcc-4.8
     472    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     473    LDFLAGS: "-m32"
     474  script: env; rake --verbose all test
     475Test gcc-4.8 32bit_nan:
     476  stage: test
     477  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     478  variables:
     479    CC: gcc-4.8
     480    CXX: g++-4.8
     481    LD: gcc-4.8
     482    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     483    LDFLAGS: "-m32"
     484  script: env; rake --verbose all test
     485Test gcc-4.8 32bit_nan_utf8:
     486  stage: test
     487  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     488  variables:
     489    CC: gcc-4.8
     490    CXX: g++-4.8
     491    LD: gcc-4.8
     492    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     493    LDFLAGS: "-m32"
     494  script: env; rake --verbose all test
     495Test gcc-4.8 32bit_word:
    336496  stage: test
    337497  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    342502    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    343503    LDFLAGS: "-m32"
    344   script: env; ./minirake --verbose all test
    345 Test gcc-4.8 32bit_utf8:
     504  script: env; rake --verbose all test
     505Test gcc-4.8 32bit_word_utf8:
    346506  stage: test
    347507  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    352512    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    353513    LDFLAGS: "-m32"
    354   script: env; ./minirake --verbose all test
    355 Test gcc-4.8 32bit_nan:
    356   stage: test
    357   image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
    358   variables:
    359     CC: gcc-4.8
    360     CXX: g++-4.8
    361     LD: gcc-4.8
    362     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    363     LDFLAGS: "-m32"
    364   script: env; ./minirake --verbose all test
    365 Test gcc-4.8 32bit_nan_utf8:
    366   stage: test
    367   image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
    368   variables:
    369     CC: gcc-4.8
    370     CXX: g++-4.8
    371     LD: gcc-4.8
    372     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    373     LDFLAGS: "-m32"
    374   script: env; ./minirake --verbose all test
     514  script: env; rake --verbose all test
    375515Test gcc-4.8 32bit_int16:
    376516  stage: test
     
    382522    CFLAGS: "-m32 -DMRB_INT16=1"
    383523    LDFLAGS: "-m32"
    384   script: env; ./minirake --verbose all test
     524  script: env; rake --verbose all test
    385525Test gcc-4.8 32bit_int16_utf8:
    386526  stage: test
     
    392532    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    393533    LDFLAGS: "-m32"
    394   script: env; ./minirake --verbose all test
     534  script: env; rake --verbose all test
    395535Test gcc-4.8 32bit_int16_nan:
    396536  stage: test
     
    402542    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    403543    LDFLAGS: "-m32"
    404   script: env; ./minirake --verbose all test
     544  script: env; rake --verbose all test
    405545Test gcc-4.8 32bit_int16_nan_utf8:
    406546  stage: test
     
    412552    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    413553    LDFLAGS: "-m32"
    414   script: env; ./minirake --verbose all test
     554  script: env; rake --verbose all test
    415555Test gcc-4.8 32bit_int64:
    416556  stage: test
     
    422562    CFLAGS: "-m32 -DMRB_INT64=1"
    423563    LDFLAGS: "-m32"
    424   script: env; ./minirake --verbose all test
     564  script: env; rake --verbose all test
    425565Test gcc-4.8 32bit_int64_utf8:
    426566  stage: test
     
    432572    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    433573    LDFLAGS: "-m32"
    434   script: env; ./minirake --verbose all test
     574  script: env; rake --verbose all test
    435575Test gcc-4.8 32bit_float:
     576  stage: test
     577  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     578  variables:
     579    CC: gcc-4.8
     580    CXX: g++-4.8
     581    LD: gcc-4.8
     582    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     583    LDFLAGS: "-m32"
     584  script: env; rake --verbose all test
     585Test gcc-4.8 32bit_float_utf8:
     586  stage: test
     587  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     588  variables:
     589    CC: gcc-4.8
     590    CXX: g++-4.8
     591    LD: gcc-4.8
     592    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     593    LDFLAGS: "-m32"
     594  script: env; rake --verbose all test
     595Test gcc-4.8 32bit_float_word:
    436596  stage: test
    437597  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    442602    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    443603    LDFLAGS: "-m32"
    444   script: env; ./minirake --verbose all test
    445 Test gcc-4.8 32bit_float_utf8:
     604  script: env; rake --verbose all test
     605Test gcc-4.8 32bit_float_word_utf8:
    446606  stage: test
    447607  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    452612    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    453613    LDFLAGS: "-m32"
    454   script: env; ./minirake --verbose all test
     614  script: env; rake --verbose all test
    455615Test gcc-4.8 32bit_float_int16:
    456616  stage: test
     
    462622    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    463623    LDFLAGS: "-m32"
    464   script: env; ./minirake --verbose all test
     624  script: env; rake --verbose all test
    465625Test gcc-4.8 32bit_float_int16_utf8:
    466626  stage: test
     
    472632    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    473633    LDFLAGS: "-m32"
    474   script: env; ./minirake --verbose all test
     634  script: env; rake --verbose all test
    475635Test gcc-4.8 32bit_float_int64:
    476636  stage: test
     
    482642    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    483643    LDFLAGS: "-m32"
    484   script: env; ./minirake --verbose all test
     644  script: env; rake --verbose all test
    485645Test gcc-4.8 32bit_float_int64_utf8:
    486646  stage: test
     
    492652    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    493653    LDFLAGS: "-m32"
    494   script: env; ./minirake --verbose all test
     654  script: env; rake --verbose all test
    495655Test gcc-4.8 64bit:
     656  stage: test
     657  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     658  variables:
     659    CC: gcc-4.8
     660    CXX: g++-4.8
     661    LD: gcc-4.8
     662    CFLAGS: ''
     663    LDFLAGS: ''
     664  script: env; rake --verbose all test
     665Test gcc-4.8 64bit_utf8:
     666  stage: test
     667  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     668  variables:
     669    CC: gcc-4.8
     670    CXX: g++-4.8
     671    LD: gcc-4.8
     672    CFLAGS: "-DMRB_UTF8_STRING=1"
     673    LDFLAGS: ''
     674  script: env; rake --verbose all test
     675Test gcc-4.8 64bit_nan:
     676  stage: test
     677  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     678  variables:
     679    CC: gcc-4.8
     680    CXX: g++-4.8
     681    LD: gcc-4.8
     682    CFLAGS: "-DMRB_NAN_BOXING=1"
     683    LDFLAGS: ''
     684  script: env; rake --verbose all test
     685Test gcc-4.8 64bit_nan_utf8:
     686  stage: test
     687  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     688  variables:
     689    CC: gcc-4.8
     690    CXX: g++-4.8
     691    LD: gcc-4.8
     692    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     693    LDFLAGS: ''
     694  script: env; rake --verbose all test
     695Test gcc-4.8 64bit_word:
    496696  stage: test
    497697  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    502702    CFLAGS: "-DMRB_WORD_BOXING=1"
    503703    LDFLAGS: ''
    504   script: env; ./minirake --verbose all test
    505 Test gcc-4.8 64bit_utf8:
     704  script: env; rake --verbose all test
     705Test gcc-4.8 64bit_word_utf8:
    506706  stage: test
    507707  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    512712    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    513713    LDFLAGS: ''
    514   script: env; ./minirake --verbose all test
    515 Test gcc-4.8 64bit_nan:
    516   stage: test
    517   image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
    518   variables:
    519     CC: gcc-4.8
    520     CXX: g++-4.8
    521     LD: gcc-4.8
    522     CFLAGS: "-DMRB_NAN_BOXING=1"
    523     LDFLAGS: ''
    524   script: env; ./minirake --verbose all test
    525 Test gcc-4.8 64bit_nan_utf8:
    526   stage: test
    527   image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
    528   variables:
    529     CC: gcc-4.8
    530     CXX: g++-4.8
    531     LD: gcc-4.8
    532     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    533     LDFLAGS: ''
    534   script: env; ./minirake --verbose all test
     714  script: env; rake --verbose all test
    535715Test gcc-4.8 64bit_int16:
    536716  stage: test
     
    542722    CFLAGS: "-DMRB_INT16=1"
    543723    LDFLAGS: ''
    544   script: env; ./minirake --verbose all test
     724  script: env; rake --verbose all test
    545725Test gcc-4.8 64bit_int16_utf8:
    546726  stage: test
     
    552732    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    553733    LDFLAGS: ''
    554   script: env; ./minirake --verbose all test
     734  script: env; rake --verbose all test
    555735Test gcc-4.8 64bit_int16_nan:
    556736  stage: test
     
    562742    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    563743    LDFLAGS: ''
    564   script: env; ./minirake --verbose all test
     744  script: env; rake --verbose all test
    565745Test gcc-4.8 64bit_int16_nan_utf8:
    566746  stage: test
     
    572752    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    573753    LDFLAGS: ''
    574   script: env; ./minirake --verbose all test
     754  script: env; rake --verbose all test
    575755Test gcc-4.8 64bit_int64:
     756  stage: test
     757  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     758  variables:
     759    CC: gcc-4.8
     760    CXX: g++-4.8
     761    LD: gcc-4.8
     762    CFLAGS: "-DMRB_INT64=1"
     763    LDFLAGS: ''
     764  script: env; rake --verbose all test
     765Test gcc-4.8 64bit_int64_utf8:
     766  stage: test
     767  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     768  variables:
     769    CC: gcc-4.8
     770    CXX: g++-4.8
     771    LD: gcc-4.8
     772    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     773    LDFLAGS: ''
     774  script: env; rake --verbose all test
     775Test gcc-4.8 64bit_int64_word:
    576776  stage: test
    577777  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    582782    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    583783    LDFLAGS: ''
    584   script: env; ./minirake --verbose all test
    585 Test gcc-4.8 64bit_int64_utf8:
     784  script: env; rake --verbose all test
     785Test gcc-4.8 64bit_int64_word_utf8:
    586786  stage: test
    587787  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    592792    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    593793    LDFLAGS: ''
    594   script: env; ./minirake --verbose all test
     794  script: env; rake --verbose all test
    595795Test gcc-4.8 64bit_float:
     796  stage: test
     797  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     798  variables:
     799    CC: gcc-4.8
     800    CXX: g++-4.8
     801    LD: gcc-4.8
     802    CFLAGS: "-DMRB_USE_FLOAT=1"
     803    LDFLAGS: ''
     804  script: env; rake --verbose all test
     805Test gcc-4.8 64bit_float_utf8:
     806  stage: test
     807  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     808  variables:
     809    CC: gcc-4.8
     810    CXX: g++-4.8
     811    LD: gcc-4.8
     812    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     813    LDFLAGS: ''
     814  script: env; rake --verbose all test
     815Test gcc-4.8 64bit_float_word:
    596816  stage: test
    597817  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    602822    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    603823    LDFLAGS: ''
    604   script: env; ./minirake --verbose all test
    605 Test gcc-4.8 64bit_float_utf8:
     824  script: env; rake --verbose all test
     825Test gcc-4.8 64bit_float_word_utf8:
    606826  stage: test
    607827  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    612832    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    613833    LDFLAGS: ''
    614   script: env; ./minirake --verbose all test
     834  script: env; rake --verbose all test
    615835Test gcc-4.8 64bit_float_int16:
    616836  stage: test
     
    622842    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    623843    LDFLAGS: ''
    624   script: env; ./minirake --verbose all test
     844  script: env; rake --verbose all test
    625845Test gcc-4.8 64bit_float_int16_utf8:
    626846  stage: test
     
    632852    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    633853    LDFLAGS: ''
    634   script: env; ./minirake --verbose all test
     854  script: env; rake --verbose all test
    635855Test gcc-4.8 64bit_float_int64:
     856  stage: test
     857  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     858  variables:
     859    CC: gcc-4.8
     860    CXX: g++-4.8
     861    LD: gcc-4.8
     862    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     863    LDFLAGS: ''
     864  script: env; rake --verbose all test
     865Test gcc-4.8 64bit_float_int64_utf8:
     866  stage: test
     867  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     868  variables:
     869    CC: gcc-4.8
     870    CXX: g++-4.8
     871    LD: gcc-4.8
     872    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     873    LDFLAGS: ''
     874  script: env; rake --verbose all test
     875Test gcc-4.8 64bit_float_int64_word:
    636876  stage: test
    637877  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    642882    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    643883    LDFLAGS: ''
    644   script: env; ./minirake --verbose all test
    645 Test gcc-4.8 64bit_float_int64_utf8:
     884  script: env; rake --verbose all test
     885Test gcc-4.8 64bit_float_int64_word_utf8:
    646886  stage: test
    647887  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
     
    652892    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    653893    LDFLAGS: ''
    654   script: env; ./minirake --verbose all test
     894  script: env; rake --verbose all test
    655895Test gcc-4.9 32bit:
     896  stage: test
     897  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     898  variables:
     899    CC: gcc-4.9
     900    CXX: g++-4.9
     901    LD: gcc-4.9
     902    CFLAGS: "-m32 "
     903    LDFLAGS: "-m32"
     904  script: env; rake --verbose all test
     905Test gcc-4.9 32bit_utf8:
     906  stage: test
     907  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     908  variables:
     909    CC: gcc-4.9
     910    CXX: g++-4.9
     911    LD: gcc-4.9
     912    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     913    LDFLAGS: "-m32"
     914  script: env; rake --verbose all test
     915Test gcc-4.9 32bit_nan:
     916  stage: test
     917  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     918  variables:
     919    CC: gcc-4.9
     920    CXX: g++-4.9
     921    LD: gcc-4.9
     922    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     923    LDFLAGS: "-m32"
     924  script: env; rake --verbose all test
     925Test gcc-4.9 32bit_nan_utf8:
     926  stage: test
     927  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     928  variables:
     929    CC: gcc-4.9
     930    CXX: g++-4.9
     931    LD: gcc-4.9
     932    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     933    LDFLAGS: "-m32"
     934  script: env; rake --verbose all test
     935Test gcc-4.9 32bit_word:
    656936  stage: test
    657937  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    662942    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    663943    LDFLAGS: "-m32"
    664   script: env; ./minirake --verbose all test
    665 Test gcc-4.9 32bit_utf8:
     944  script: env; rake --verbose all test
     945Test gcc-4.9 32bit_word_utf8:
    666946  stage: test
    667947  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    672952    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    673953    LDFLAGS: "-m32"
    674   script: env; ./minirake --verbose all test
    675 Test gcc-4.9 32bit_nan:
    676   stage: test
    677   image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
    678   variables:
    679     CC: gcc-4.9
    680     CXX: g++-4.9
    681     LD: gcc-4.9
    682     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    683     LDFLAGS: "-m32"
    684   script: env; ./minirake --verbose all test
    685 Test gcc-4.9 32bit_nan_utf8:
    686   stage: test
    687   image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
    688   variables:
    689     CC: gcc-4.9
    690     CXX: g++-4.9
    691     LD: gcc-4.9
    692     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    693     LDFLAGS: "-m32"
    694   script: env; ./minirake --verbose all test
     954  script: env; rake --verbose all test
    695955Test gcc-4.9 32bit_int16:
    696956  stage: test
     
    702962    CFLAGS: "-m32 -DMRB_INT16=1"
    703963    LDFLAGS: "-m32"
    704   script: env; ./minirake --verbose all test
     964  script: env; rake --verbose all test
    705965Test gcc-4.9 32bit_int16_utf8:
    706966  stage: test
     
    712972    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    713973    LDFLAGS: "-m32"
    714   script: env; ./minirake --verbose all test
     974  script: env; rake --verbose all test
    715975Test gcc-4.9 32bit_int16_nan:
    716976  stage: test
     
    722982    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    723983    LDFLAGS: "-m32"
    724   script: env; ./minirake --verbose all test
     984  script: env; rake --verbose all test
    725985Test gcc-4.9 32bit_int16_nan_utf8:
    726986  stage: test
     
    732992    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    733993    LDFLAGS: "-m32"
    734   script: env; ./minirake --verbose all test
     994  script: env; rake --verbose all test
    735995Test gcc-4.9 32bit_int64:
    736996  stage: test
     
    7421002    CFLAGS: "-m32 -DMRB_INT64=1"
    7431003    LDFLAGS: "-m32"
    744   script: env; ./minirake --verbose all test
     1004  script: env; rake --verbose all test
    7451005Test gcc-4.9 32bit_int64_utf8:
    7461006  stage: test
     
    7521012    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    7531013    LDFLAGS: "-m32"
    754   script: env; ./minirake --verbose all test
     1014  script: env; rake --verbose all test
    7551015Test gcc-4.9 32bit_float:
     1016  stage: test
     1017  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1018  variables:
     1019    CC: gcc-4.9
     1020    CXX: g++-4.9
     1021    LD: gcc-4.9
     1022    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     1023    LDFLAGS: "-m32"
     1024  script: env; rake --verbose all test
     1025Test gcc-4.9 32bit_float_utf8:
     1026  stage: test
     1027  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1028  variables:
     1029    CC: gcc-4.9
     1030    CXX: g++-4.9
     1031    LD: gcc-4.9
     1032    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     1033    LDFLAGS: "-m32"
     1034  script: env; rake --verbose all test
     1035Test gcc-4.9 32bit_float_word:
    7561036  stage: test
    7571037  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    7621042    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    7631043    LDFLAGS: "-m32"
    764   script: env; ./minirake --verbose all test
    765 Test gcc-4.9 32bit_float_utf8:
     1044  script: env; rake --verbose all test
     1045Test gcc-4.9 32bit_float_word_utf8:
    7661046  stage: test
    7671047  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    7721052    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    7731053    LDFLAGS: "-m32"
    774   script: env; ./minirake --verbose all test
     1054  script: env; rake --verbose all test
    7751055Test gcc-4.9 32bit_float_int16:
    7761056  stage: test
     
    7821062    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    7831063    LDFLAGS: "-m32"
    784   script: env; ./minirake --verbose all test
     1064  script: env; rake --verbose all test
    7851065Test gcc-4.9 32bit_float_int16_utf8:
    7861066  stage: test
     
    7921072    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    7931073    LDFLAGS: "-m32"
    794   script: env; ./minirake --verbose all test
     1074  script: env; rake --verbose all test
    7951075Test gcc-4.9 32bit_float_int64:
    7961076  stage: test
     
    8021082    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    8031083    LDFLAGS: "-m32"
    804   script: env; ./minirake --verbose all test
     1084  script: env; rake --verbose all test
    8051085Test gcc-4.9 32bit_float_int64_utf8:
    8061086  stage: test
     
    8121092    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    8131093    LDFLAGS: "-m32"
    814   script: env; ./minirake --verbose all test
     1094  script: env; rake --verbose all test
    8151095Test gcc-4.9 64bit:
     1096  stage: test
     1097  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1098  variables:
     1099    CC: gcc-4.9
     1100    CXX: g++-4.9
     1101    LD: gcc-4.9
     1102    CFLAGS: ''
     1103    LDFLAGS: ''
     1104  script: env; rake --verbose all test
     1105Test gcc-4.9 64bit_utf8:
     1106  stage: test
     1107  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1108  variables:
     1109    CC: gcc-4.9
     1110    CXX: g++-4.9
     1111    LD: gcc-4.9
     1112    CFLAGS: "-DMRB_UTF8_STRING=1"
     1113    LDFLAGS: ''
     1114  script: env; rake --verbose all test
     1115Test gcc-4.9 64bit_nan:
     1116  stage: test
     1117  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1118  variables:
     1119    CC: gcc-4.9
     1120    CXX: g++-4.9
     1121    LD: gcc-4.9
     1122    CFLAGS: "-DMRB_NAN_BOXING=1"
     1123    LDFLAGS: ''
     1124  script: env; rake --verbose all test
     1125Test gcc-4.9 64bit_nan_utf8:
     1126  stage: test
     1127  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1128  variables:
     1129    CC: gcc-4.9
     1130    CXX: g++-4.9
     1131    LD: gcc-4.9
     1132    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     1133    LDFLAGS: ''
     1134  script: env; rake --verbose all test
     1135Test gcc-4.9 64bit_word:
    8161136  stage: test
    8171137  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    8221142    CFLAGS: "-DMRB_WORD_BOXING=1"
    8231143    LDFLAGS: ''
    824   script: env; ./minirake --verbose all test
    825 Test gcc-4.9 64bit_utf8:
     1144  script: env; rake --verbose all test
     1145Test gcc-4.9 64bit_word_utf8:
    8261146  stage: test
    8271147  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    8321152    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    8331153    LDFLAGS: ''
    834   script: env; ./minirake --verbose all test
    835 Test gcc-4.9 64bit_nan:
    836   stage: test
    837   image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
    838   variables:
    839     CC: gcc-4.9
    840     CXX: g++-4.9
    841     LD: gcc-4.9
    842     CFLAGS: "-DMRB_NAN_BOXING=1"
    843     LDFLAGS: ''
    844   script: env; ./minirake --verbose all test
    845 Test gcc-4.9 64bit_nan_utf8:
    846   stage: test
    847   image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
    848   variables:
    849     CC: gcc-4.9
    850     CXX: g++-4.9
    851     LD: gcc-4.9
    852     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    853     LDFLAGS: ''
    854   script: env; ./minirake --verbose all test
     1154  script: env; rake --verbose all test
    8551155Test gcc-4.9 64bit_int16:
    8561156  stage: test
     
    8621162    CFLAGS: "-DMRB_INT16=1"
    8631163    LDFLAGS: ''
    864   script: env; ./minirake --verbose all test
     1164  script: env; rake --verbose all test
    8651165Test gcc-4.9 64bit_int16_utf8:
    8661166  stage: test
     
    8721172    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    8731173    LDFLAGS: ''
    874   script: env; ./minirake --verbose all test
     1174  script: env; rake --verbose all test
    8751175Test gcc-4.9 64bit_int16_nan:
    8761176  stage: test
     
    8821182    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    8831183    LDFLAGS: ''
    884   script: env; ./minirake --verbose all test
     1184  script: env; rake --verbose all test
    8851185Test gcc-4.9 64bit_int16_nan_utf8:
    8861186  stage: test
     
    8921192    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    8931193    LDFLAGS: ''
    894   script: env; ./minirake --verbose all test
     1194  script: env; rake --verbose all test
    8951195Test gcc-4.9 64bit_int64:
     1196  stage: test
     1197  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1198  variables:
     1199    CC: gcc-4.9
     1200    CXX: g++-4.9
     1201    LD: gcc-4.9
     1202    CFLAGS: "-DMRB_INT64=1"
     1203    LDFLAGS: ''
     1204  script: env; rake --verbose all test
     1205Test gcc-4.9 64bit_int64_utf8:
     1206  stage: test
     1207  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1208  variables:
     1209    CC: gcc-4.9
     1210    CXX: g++-4.9
     1211    LD: gcc-4.9
     1212    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     1213    LDFLAGS: ''
     1214  script: env; rake --verbose all test
     1215Test gcc-4.9 64bit_int64_word:
    8961216  stage: test
    8971217  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    9021222    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    9031223    LDFLAGS: ''
    904   script: env; ./minirake --verbose all test
    905 Test gcc-4.9 64bit_int64_utf8:
     1224  script: env; rake --verbose all test
     1225Test gcc-4.9 64bit_int64_word_utf8:
    9061226  stage: test
    9071227  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    9121232    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    9131233    LDFLAGS: ''
    914   script: env; ./minirake --verbose all test
     1234  script: env; rake --verbose all test
    9151235Test gcc-4.9 64bit_float:
     1236  stage: test
     1237  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1238  variables:
     1239    CC: gcc-4.9
     1240    CXX: g++-4.9
     1241    LD: gcc-4.9
     1242    CFLAGS: "-DMRB_USE_FLOAT=1"
     1243    LDFLAGS: ''
     1244  script: env; rake --verbose all test
     1245Test gcc-4.9 64bit_float_utf8:
     1246  stage: test
     1247  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1248  variables:
     1249    CC: gcc-4.9
     1250    CXX: g++-4.9
     1251    LD: gcc-4.9
     1252    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     1253    LDFLAGS: ''
     1254  script: env; rake --verbose all test
     1255Test gcc-4.9 64bit_float_word:
    9161256  stage: test
    9171257  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    9221262    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    9231263    LDFLAGS: ''
    924   script: env; ./minirake --verbose all test
    925 Test gcc-4.9 64bit_float_utf8:
     1264  script: env; rake --verbose all test
     1265Test gcc-4.9 64bit_float_word_utf8:
    9261266  stage: test
    9271267  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    9321272    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    9331273    LDFLAGS: ''
    934   script: env; ./minirake --verbose all test
     1274  script: env; rake --verbose all test
    9351275Test gcc-4.9 64bit_float_int16:
    9361276  stage: test
     
    9421282    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    9431283    LDFLAGS: ''
    944   script: env; ./minirake --verbose all test
     1284  script: env; rake --verbose all test
    9451285Test gcc-4.9 64bit_float_int16_utf8:
    9461286  stage: test
     
    9521292    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    9531293    LDFLAGS: ''
    954   script: env; ./minirake --verbose all test
     1294  script: env; rake --verbose all test
    9551295Test gcc-4.9 64bit_float_int64:
     1296  stage: test
     1297  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1298  variables:
     1299    CC: gcc-4.9
     1300    CXX: g++-4.9
     1301    LD: gcc-4.9
     1302    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     1303    LDFLAGS: ''
     1304  script: env; rake --verbose all test
     1305Test gcc-4.9 64bit_float_int64_utf8:
     1306  stage: test
     1307  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     1308  variables:
     1309    CC: gcc-4.9
     1310    CXX: g++-4.9
     1311    LD: gcc-4.9
     1312    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     1313    LDFLAGS: ''
     1314  script: env; rake --verbose all test
     1315Test gcc-4.9 64bit_float_int64_word:
    9561316  stage: test
    9571317  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    9621322    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    9631323    LDFLAGS: ''
    964   script: env; ./minirake --verbose all test
    965 Test gcc-4.9 64bit_float_int64_utf8:
     1324  script: env; rake --verbose all test
     1325Test gcc-4.9 64bit_float_int64_word_utf8:
    9661326  stage: test
    9671327  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
     
    9721332    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    9731333    LDFLAGS: ''
    974   script: env; ./minirake --verbose all test
     1334  script: env; rake --verbose all test
    9751335Test gcc-5 32bit:
     1336  stage: test
     1337  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1338  variables:
     1339    CC: gcc-5
     1340    CXX: g++-5
     1341    LD: gcc-5
     1342    CFLAGS: "-m32 "
     1343    LDFLAGS: "-m32"
     1344  script: env; rake --verbose all test
     1345Test gcc-5 32bit_utf8:
     1346  stage: test
     1347  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1348  variables:
     1349    CC: gcc-5
     1350    CXX: g++-5
     1351    LD: gcc-5
     1352    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     1353    LDFLAGS: "-m32"
     1354  script: env; rake --verbose all test
     1355Test gcc-5 32bit_nan:
     1356  stage: test
     1357  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1358  variables:
     1359    CC: gcc-5
     1360    CXX: g++-5
     1361    LD: gcc-5
     1362    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     1363    LDFLAGS: "-m32"
     1364  script: env; rake --verbose all test
     1365Test gcc-5 32bit_nan_utf8:
     1366  stage: test
     1367  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1368  variables:
     1369    CC: gcc-5
     1370    CXX: g++-5
     1371    LD: gcc-5
     1372    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     1373    LDFLAGS: "-m32"
     1374  script: env; rake --verbose all test
     1375Test gcc-5 32bit_word:
    9761376  stage: test
    9771377  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    9821382    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    9831383    LDFLAGS: "-m32"
    984   script: env; ./minirake --verbose all test
    985 Test gcc-5 32bit_utf8:
     1384  script: env; rake --verbose all test
     1385Test gcc-5 32bit_word_utf8:
    9861386  stage: test
    9871387  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    9921392    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    9931393    LDFLAGS: "-m32"
    994   script: env; ./minirake --verbose all test
    995 Test gcc-5 32bit_nan:
    996   stage: test
    997   image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
    998   variables:
    999     CC: gcc-5
    1000     CXX: g++-5
    1001     LD: gcc-5
    1002     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    1003     LDFLAGS: "-m32"
    1004   script: env; ./minirake --verbose all test
    1005 Test gcc-5 32bit_nan_utf8:
    1006   stage: test
    1007   image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
    1008   variables:
    1009     CC: gcc-5
    1010     CXX: g++-5
    1011     LD: gcc-5
    1012     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    1013     LDFLAGS: "-m32"
    1014   script: env; ./minirake --verbose all test
     1394  script: env; rake --verbose all test
    10151395Test gcc-5 32bit_int16:
    10161396  stage: test
     
    10221402    CFLAGS: "-m32 -DMRB_INT16=1"
    10231403    LDFLAGS: "-m32"
    1024   script: env; ./minirake --verbose all test
     1404  script: env; rake --verbose all test
    10251405Test gcc-5 32bit_int16_utf8:
    10261406  stage: test
     
    10321412    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    10331413    LDFLAGS: "-m32"
    1034   script: env; ./minirake --verbose all test
     1414  script: env; rake --verbose all test
    10351415Test gcc-5 32bit_int16_nan:
    10361416  stage: test
     
    10421422    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    10431423    LDFLAGS: "-m32"
    1044   script: env; ./minirake --verbose all test
     1424  script: env; rake --verbose all test
    10451425Test gcc-5 32bit_int16_nan_utf8:
    10461426  stage: test
     
    10521432    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    10531433    LDFLAGS: "-m32"
    1054   script: env; ./minirake --verbose all test
     1434  script: env; rake --verbose all test
    10551435Test gcc-5 32bit_int64:
    10561436  stage: test
     
    10621442    CFLAGS: "-m32 -DMRB_INT64=1"
    10631443    LDFLAGS: "-m32"
    1064   script: env; ./minirake --verbose all test
     1444  script: env; rake --verbose all test
    10651445Test gcc-5 32bit_int64_utf8:
    10661446  stage: test
     
    10721452    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    10731453    LDFLAGS: "-m32"
    1074   script: env; ./minirake --verbose all test
     1454  script: env; rake --verbose all test
    10751455Test gcc-5 32bit_float:
     1456  stage: test
     1457  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1458  variables:
     1459    CC: gcc-5
     1460    CXX: g++-5
     1461    LD: gcc-5
     1462    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     1463    LDFLAGS: "-m32"
     1464  script: env; rake --verbose all test
     1465Test gcc-5 32bit_float_utf8:
     1466  stage: test
     1467  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1468  variables:
     1469    CC: gcc-5
     1470    CXX: g++-5
     1471    LD: gcc-5
     1472    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     1473    LDFLAGS: "-m32"
     1474  script: env; rake --verbose all test
     1475Test gcc-5 32bit_float_word:
    10761476  stage: test
    10771477  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    10821482    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    10831483    LDFLAGS: "-m32"
    1084   script: env; ./minirake --verbose all test
    1085 Test gcc-5 32bit_float_utf8:
     1484  script: env; rake --verbose all test
     1485Test gcc-5 32bit_float_word_utf8:
    10861486  stage: test
    10871487  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    10921492    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    10931493    LDFLAGS: "-m32"
    1094   script: env; ./minirake --verbose all test
     1494  script: env; rake --verbose all test
    10951495Test gcc-5 32bit_float_int16:
    10961496  stage: test
     
    11021502    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    11031503    LDFLAGS: "-m32"
    1104   script: env; ./minirake --verbose all test
     1504  script: env; rake --verbose all test
    11051505Test gcc-5 32bit_float_int16_utf8:
    11061506  stage: test
     
    11121512    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    11131513    LDFLAGS: "-m32"
    1114   script: env; ./minirake --verbose all test
     1514  script: env; rake --verbose all test
    11151515Test gcc-5 32bit_float_int64:
    11161516  stage: test
     
    11221522    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    11231523    LDFLAGS: "-m32"
    1124   script: env; ./minirake --verbose all test
     1524  script: env; rake --verbose all test
    11251525Test gcc-5 32bit_float_int64_utf8:
    11261526  stage: test
     
    11321532    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    11331533    LDFLAGS: "-m32"
    1134   script: env; ./minirake --verbose all test
     1534  script: env; rake --verbose all test
    11351535Test gcc-5 64bit:
     1536  stage: test
     1537  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1538  variables:
     1539    CC: gcc-5
     1540    CXX: g++-5
     1541    LD: gcc-5
     1542    CFLAGS: ''
     1543    LDFLAGS: ''
     1544  script: env; rake --verbose all test
     1545Test gcc-5 64bit_utf8:
     1546  stage: test
     1547  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1548  variables:
     1549    CC: gcc-5
     1550    CXX: g++-5
     1551    LD: gcc-5
     1552    CFLAGS: "-DMRB_UTF8_STRING=1"
     1553    LDFLAGS: ''
     1554  script: env; rake --verbose all test
     1555Test gcc-5 64bit_nan:
     1556  stage: test
     1557  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1558  variables:
     1559    CC: gcc-5
     1560    CXX: g++-5
     1561    LD: gcc-5
     1562    CFLAGS: "-DMRB_NAN_BOXING=1"
     1563    LDFLAGS: ''
     1564  script: env; rake --verbose all test
     1565Test gcc-5 64bit_nan_utf8:
     1566  stage: test
     1567  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1568  variables:
     1569    CC: gcc-5
     1570    CXX: g++-5
     1571    LD: gcc-5
     1572    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     1573    LDFLAGS: ''
     1574  script: env; rake --verbose all test
     1575Test gcc-5 64bit_word:
    11361576  stage: test
    11371577  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    11421582    CFLAGS: "-DMRB_WORD_BOXING=1"
    11431583    LDFLAGS: ''
    1144   script: env; ./minirake --verbose all test
    1145 Test gcc-5 64bit_utf8:
     1584  script: env; rake --verbose all test
     1585Test gcc-5 64bit_word_utf8:
    11461586  stage: test
    11471587  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    11521592    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    11531593    LDFLAGS: ''
    1154   script: env; ./minirake --verbose all test
    1155 Test gcc-5 64bit_nan:
    1156   stage: test
    1157   image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
    1158   variables:
    1159     CC: gcc-5
    1160     CXX: g++-5
    1161     LD: gcc-5
    1162     CFLAGS: "-DMRB_NAN_BOXING=1"
    1163     LDFLAGS: ''
    1164   script: env; ./minirake --verbose all test
    1165 Test gcc-5 64bit_nan_utf8:
    1166   stage: test
    1167   image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
    1168   variables:
    1169     CC: gcc-5
    1170     CXX: g++-5
    1171     LD: gcc-5
    1172     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    1173     LDFLAGS: ''
    1174   script: env; ./minirake --verbose all test
     1594  script: env; rake --verbose all test
    11751595Test gcc-5 64bit_int16:
    11761596  stage: test
     
    11821602    CFLAGS: "-DMRB_INT16=1"
    11831603    LDFLAGS: ''
    1184   script: env; ./minirake --verbose all test
     1604  script: env; rake --verbose all test
    11851605Test gcc-5 64bit_int16_utf8:
    11861606  stage: test
     
    11921612    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    11931613    LDFLAGS: ''
    1194   script: env; ./minirake --verbose all test
     1614  script: env; rake --verbose all test
    11951615Test gcc-5 64bit_int16_nan:
    11961616  stage: test
     
    12021622    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    12031623    LDFLAGS: ''
    1204   script: env; ./minirake --verbose all test
     1624  script: env; rake --verbose all test
    12051625Test gcc-5 64bit_int16_nan_utf8:
    12061626  stage: test
     
    12121632    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    12131633    LDFLAGS: ''
    1214   script: env; ./minirake --verbose all test
     1634  script: env; rake --verbose all test
    12151635Test gcc-5 64bit_int64:
     1636  stage: test
     1637  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1638  variables:
     1639    CC: gcc-5
     1640    CXX: g++-5
     1641    LD: gcc-5
     1642    CFLAGS: "-DMRB_INT64=1"
     1643    LDFLAGS: ''
     1644  script: env; rake --verbose all test
     1645Test gcc-5 64bit_int64_utf8:
     1646  stage: test
     1647  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1648  variables:
     1649    CC: gcc-5
     1650    CXX: g++-5
     1651    LD: gcc-5
     1652    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     1653    LDFLAGS: ''
     1654  script: env; rake --verbose all test
     1655Test gcc-5 64bit_int64_word:
    12161656  stage: test
    12171657  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    12221662    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    12231663    LDFLAGS: ''
    1224   script: env; ./minirake --verbose all test
    1225 Test gcc-5 64bit_int64_utf8:
     1664  script: env; rake --verbose all test
     1665Test gcc-5 64bit_int64_word_utf8:
    12261666  stage: test
    12271667  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    12321672    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    12331673    LDFLAGS: ''
    1234   script: env; ./minirake --verbose all test
     1674  script: env; rake --verbose all test
    12351675Test gcc-5 64bit_float:
     1676  stage: test
     1677  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1678  variables:
     1679    CC: gcc-5
     1680    CXX: g++-5
     1681    LD: gcc-5
     1682    CFLAGS: "-DMRB_USE_FLOAT=1"
     1683    LDFLAGS: ''
     1684  script: env; rake --verbose all test
     1685Test gcc-5 64bit_float_utf8:
     1686  stage: test
     1687  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1688  variables:
     1689    CC: gcc-5
     1690    CXX: g++-5
     1691    LD: gcc-5
     1692    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     1693    LDFLAGS: ''
     1694  script: env; rake --verbose all test
     1695Test gcc-5 64bit_float_word:
    12361696  stage: test
    12371697  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    12421702    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    12431703    LDFLAGS: ''
    1244   script: env; ./minirake --verbose all test
    1245 Test gcc-5 64bit_float_utf8:
     1704  script: env; rake --verbose all test
     1705Test gcc-5 64bit_float_word_utf8:
    12461706  stage: test
    12471707  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    12521712    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    12531713    LDFLAGS: ''
    1254   script: env; ./minirake --verbose all test
     1714  script: env; rake --verbose all test
    12551715Test gcc-5 64bit_float_int16:
    12561716  stage: test
     
    12621722    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    12631723    LDFLAGS: ''
    1264   script: env; ./minirake --verbose all test
     1724  script: env; rake --verbose all test
    12651725Test gcc-5 64bit_float_int16_utf8:
    12661726  stage: test
     
    12721732    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    12731733    LDFLAGS: ''
    1274   script: env; ./minirake --verbose all test
     1734  script: env; rake --verbose all test
    12751735Test gcc-5 64bit_float_int64:
     1736  stage: test
     1737  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1738  variables:
     1739    CC: gcc-5
     1740    CXX: g++-5
     1741    LD: gcc-5
     1742    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     1743    LDFLAGS: ''
     1744  script: env; rake --verbose all test
     1745Test gcc-5 64bit_float_int64_utf8:
     1746  stage: test
     1747  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     1748  variables:
     1749    CC: gcc-5
     1750    CXX: g++-5
     1751    LD: gcc-5
     1752    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     1753    LDFLAGS: ''
     1754  script: env; rake --verbose all test
     1755Test gcc-5 64bit_float_int64_word:
    12761756  stage: test
    12771757  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    12821762    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    12831763    LDFLAGS: ''
    1284   script: env; ./minirake --verbose all test
    1285 Test gcc-5 64bit_float_int64_utf8:
     1764  script: env; rake --verbose all test
     1765Test gcc-5 64bit_float_int64_word_utf8:
    12861766  stage: test
    12871767  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
     
    12921772    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    12931773    LDFLAGS: ''
    1294   script: env; ./minirake --verbose all test
     1774  script: env; rake --verbose all test
    12951775Test gcc-6 32bit:
     1776  stage: test
     1777  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1778  variables:
     1779    CC: gcc-6
     1780    CXX: g++-6
     1781    LD: gcc-6
     1782    CFLAGS: "-m32 "
     1783    LDFLAGS: "-m32"
     1784  script: env; rake --verbose all test
     1785Test gcc-6 32bit_utf8:
     1786  stage: test
     1787  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1788  variables:
     1789    CC: gcc-6
     1790    CXX: g++-6
     1791    LD: gcc-6
     1792    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     1793    LDFLAGS: "-m32"
     1794  script: env; rake --verbose all test
     1795Test gcc-6 32bit_nan:
     1796  stage: test
     1797  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1798  variables:
     1799    CC: gcc-6
     1800    CXX: g++-6
     1801    LD: gcc-6
     1802    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     1803    LDFLAGS: "-m32"
     1804  script: env; rake --verbose all test
     1805Test gcc-6 32bit_nan_utf8:
     1806  stage: test
     1807  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1808  variables:
     1809    CC: gcc-6
     1810    CXX: g++-6
     1811    LD: gcc-6
     1812    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     1813    LDFLAGS: "-m32"
     1814  script: env; rake --verbose all test
     1815Test gcc-6 32bit_word:
    12961816  stage: test
    12971817  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    13021822    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    13031823    LDFLAGS: "-m32"
    1304   script: env; ./minirake --verbose all test
    1305 Test gcc-6 32bit_utf8:
     1824  script: env; rake --verbose all test
     1825Test gcc-6 32bit_word_utf8:
    13061826  stage: test
    13071827  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    13121832    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    13131833    LDFLAGS: "-m32"
    1314   script: env; ./minirake --verbose all test
    1315 Test gcc-6 32bit_nan:
    1316   stage: test
    1317   image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
    1318   variables:
    1319     CC: gcc-6
    1320     CXX: g++-6
    1321     LD: gcc-6
    1322     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    1323     LDFLAGS: "-m32"
    1324   script: env; ./minirake --verbose all test
    1325 Test gcc-6 32bit_nan_utf8:
    1326   stage: test
    1327   image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
    1328   variables:
    1329     CC: gcc-6
    1330     CXX: g++-6
    1331     LD: gcc-6
    1332     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    1333     LDFLAGS: "-m32"
    1334   script: env; ./minirake --verbose all test
     1834  script: env; rake --verbose all test
    13351835Test gcc-6 32bit_int16:
    13361836  stage: test
     
    13421842    CFLAGS: "-m32 -DMRB_INT16=1"
    13431843    LDFLAGS: "-m32"
    1344   script: env; ./minirake --verbose all test
     1844  script: env; rake --verbose all test
    13451845Test gcc-6 32bit_int16_utf8:
    13461846  stage: test
     
    13521852    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    13531853    LDFLAGS: "-m32"
    1354   script: env; ./minirake --verbose all test
     1854  script: env; rake --verbose all test
    13551855Test gcc-6 32bit_int16_nan:
    13561856  stage: test
     
    13621862    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    13631863    LDFLAGS: "-m32"
    1364   script: env; ./minirake --verbose all test
     1864  script: env; rake --verbose all test
    13651865Test gcc-6 32bit_int16_nan_utf8:
    13661866  stage: test
     
    13721872    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    13731873    LDFLAGS: "-m32"
    1374   script: env; ./minirake --verbose all test
     1874  script: env; rake --verbose all test
    13751875Test gcc-6 32bit_int64:
    13761876  stage: test
     
    13821882    CFLAGS: "-m32 -DMRB_INT64=1"
    13831883    LDFLAGS: "-m32"
    1384   script: env; ./minirake --verbose all test
     1884  script: env; rake --verbose all test
    13851885Test gcc-6 32bit_int64_utf8:
    13861886  stage: test
     
    13921892    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    13931893    LDFLAGS: "-m32"
    1394   script: env; ./minirake --verbose all test
     1894  script: env; rake --verbose all test
    13951895Test gcc-6 32bit_float:
     1896  stage: test
     1897  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1898  variables:
     1899    CC: gcc-6
     1900    CXX: g++-6
     1901    LD: gcc-6
     1902    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     1903    LDFLAGS: "-m32"
     1904  script: env; rake --verbose all test
     1905Test gcc-6 32bit_float_utf8:
     1906  stage: test
     1907  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1908  variables:
     1909    CC: gcc-6
     1910    CXX: g++-6
     1911    LD: gcc-6
     1912    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     1913    LDFLAGS: "-m32"
     1914  script: env; rake --verbose all test
     1915Test gcc-6 32bit_float_word:
    13961916  stage: test
    13971917  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    14021922    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    14031923    LDFLAGS: "-m32"
    1404   script: env; ./minirake --verbose all test
    1405 Test gcc-6 32bit_float_utf8:
     1924  script: env; rake --verbose all test
     1925Test gcc-6 32bit_float_word_utf8:
    14061926  stage: test
    14071927  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    14121932    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    14131933    LDFLAGS: "-m32"
    1414   script: env; ./minirake --verbose all test
     1934  script: env; rake --verbose all test
    14151935Test gcc-6 32bit_float_int16:
    14161936  stage: test
     
    14221942    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    14231943    LDFLAGS: "-m32"
    1424   script: env; ./minirake --verbose all test
     1944  script: env; rake --verbose all test
    14251945Test gcc-6 32bit_float_int16_utf8:
    14261946  stage: test
     
    14321952    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    14331953    LDFLAGS: "-m32"
    1434   script: env; ./minirake --verbose all test
     1954  script: env; rake --verbose all test
    14351955Test gcc-6 32bit_float_int64:
    14361956  stage: test
     
    14421962    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    14431963    LDFLAGS: "-m32"
    1444   script: env; ./minirake --verbose all test
     1964  script: env; rake --verbose all test
    14451965Test gcc-6 32bit_float_int64_utf8:
    14461966  stage: test
     
    14521972    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    14531973    LDFLAGS: "-m32"
    1454   script: env; ./minirake --verbose all test
     1974  script: env; rake --verbose all test
    14551975Test gcc-6 64bit:
     1976  stage: test
     1977  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1978  variables:
     1979    CC: gcc-6
     1980    CXX: g++-6
     1981    LD: gcc-6
     1982    CFLAGS: ''
     1983    LDFLAGS: ''
     1984  script: env; rake --verbose all test
     1985Test gcc-6 64bit_utf8:
     1986  stage: test
     1987  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1988  variables:
     1989    CC: gcc-6
     1990    CXX: g++-6
     1991    LD: gcc-6
     1992    CFLAGS: "-DMRB_UTF8_STRING=1"
     1993    LDFLAGS: ''
     1994  script: env; rake --verbose all test
     1995Test gcc-6 64bit_nan:
     1996  stage: test
     1997  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     1998  variables:
     1999    CC: gcc-6
     2000    CXX: g++-6
     2001    LD: gcc-6
     2002    CFLAGS: "-DMRB_NAN_BOXING=1"
     2003    LDFLAGS: ''
     2004  script: env; rake --verbose all test
     2005Test gcc-6 64bit_nan_utf8:
     2006  stage: test
     2007  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     2008  variables:
     2009    CC: gcc-6
     2010    CXX: g++-6
     2011    LD: gcc-6
     2012    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     2013    LDFLAGS: ''
     2014  script: env; rake --verbose all test
     2015Test gcc-6 64bit_word:
    14562016  stage: test
    14572017  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    14622022    CFLAGS: "-DMRB_WORD_BOXING=1"
    14632023    LDFLAGS: ''
    1464   script: env; ./minirake --verbose all test
    1465 Test gcc-6 64bit_utf8:
     2024  script: env; rake --verbose all test
     2025Test gcc-6 64bit_word_utf8:
    14662026  stage: test
    14672027  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    14722032    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    14732033    LDFLAGS: ''
    1474   script: env; ./minirake --verbose all test
    1475 Test gcc-6 64bit_nan:
    1476   stage: test
    1477   image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
    1478   variables:
    1479     CC: gcc-6
    1480     CXX: g++-6
    1481     LD: gcc-6
    1482     CFLAGS: "-DMRB_NAN_BOXING=1"
    1483     LDFLAGS: ''
    1484   script: env; ./minirake --verbose all test
    1485 Test gcc-6 64bit_nan_utf8:
    1486   stage: test
    1487   image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
    1488   variables:
    1489     CC: gcc-6
    1490     CXX: g++-6
    1491     LD: gcc-6
    1492     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    1493     LDFLAGS: ''
    1494   script: env; ./minirake --verbose all test
     2034  script: env; rake --verbose all test
    14952035Test gcc-6 64bit_int16:
    14962036  stage: test
     
    15022042    CFLAGS: "-DMRB_INT16=1"
    15032043    LDFLAGS: ''
    1504   script: env; ./minirake --verbose all test
     2044  script: env; rake --verbose all test
    15052045Test gcc-6 64bit_int16_utf8:
    15062046  stage: test
     
    15122052    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    15132053    LDFLAGS: ''
    1514   script: env; ./minirake --verbose all test
     2054  script: env; rake --verbose all test
    15152055Test gcc-6 64bit_int16_nan:
    15162056  stage: test
     
    15222062    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    15232063    LDFLAGS: ''
    1524   script: env; ./minirake --verbose all test
     2064  script: env; rake --verbose all test
    15252065Test gcc-6 64bit_int16_nan_utf8:
    15262066  stage: test
     
    15322072    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    15332073    LDFLAGS: ''
    1534   script: env; ./minirake --verbose all test
     2074  script: env; rake --verbose all test
    15352075Test gcc-6 64bit_int64:
     2076  stage: test
     2077  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     2078  variables:
     2079    CC: gcc-6
     2080    CXX: g++-6
     2081    LD: gcc-6
     2082    CFLAGS: "-DMRB_INT64=1"
     2083    LDFLAGS: ''
     2084  script: env; rake --verbose all test
     2085Test gcc-6 64bit_int64_utf8:
     2086  stage: test
     2087  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     2088  variables:
     2089    CC: gcc-6
     2090    CXX: g++-6
     2091    LD: gcc-6
     2092    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     2093    LDFLAGS: ''
     2094  script: env; rake --verbose all test
     2095Test gcc-6 64bit_int64_word:
    15362096  stage: test
    15372097  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    15422102    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    15432103    LDFLAGS: ''
    1544   script: env; ./minirake --verbose all test
    1545 Test gcc-6 64bit_int64_utf8:
     2104  script: env; rake --verbose all test
     2105Test gcc-6 64bit_int64_word_utf8:
    15462106  stage: test
    15472107  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    15522112    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    15532113    LDFLAGS: ''
    1554   script: env; ./minirake --verbose all test
     2114  script: env; rake --verbose all test
    15552115Test gcc-6 64bit_float:
     2116  stage: test
     2117  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     2118  variables:
     2119    CC: gcc-6
     2120    CXX: g++-6
     2121    LD: gcc-6
     2122    CFLAGS: "-DMRB_USE_FLOAT=1"
     2123    LDFLAGS: ''
     2124  script: env; rake --verbose all test
     2125Test gcc-6 64bit_float_utf8:
     2126  stage: test
     2127  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     2128  variables:
     2129    CC: gcc-6
     2130    CXX: g++-6
     2131    LD: gcc-6
     2132    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     2133    LDFLAGS: ''
     2134  script: env; rake --verbose all test
     2135Test gcc-6 64bit_float_word:
    15562136  stage: test
    15572137  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    15622142    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    15632143    LDFLAGS: ''
    1564   script: env; ./minirake --verbose all test
    1565 Test gcc-6 64bit_float_utf8:
     2144  script: env; rake --verbose all test
     2145Test gcc-6 64bit_float_word_utf8:
    15662146  stage: test
    15672147  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    15722152    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    15732153    LDFLAGS: ''
    1574   script: env; ./minirake --verbose all test
     2154  script: env; rake --verbose all test
    15752155Test gcc-6 64bit_float_int16:
    15762156  stage: test
     
    15822162    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    15832163    LDFLAGS: ''
    1584   script: env; ./minirake --verbose all test
     2164  script: env; rake --verbose all test
    15852165Test gcc-6 64bit_float_int16_utf8:
    15862166  stage: test
     
    15922172    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    15932173    LDFLAGS: ''
    1594   script: env; ./minirake --verbose all test
     2174  script: env; rake --verbose all test
    15952175Test gcc-6 64bit_float_int64:
     2176  stage: test
     2177  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     2178  variables:
     2179    CC: gcc-6
     2180    CXX: g++-6
     2181    LD: gcc-6
     2182    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     2183    LDFLAGS: ''
     2184  script: env; rake --verbose all test
     2185Test gcc-6 64bit_float_int64_utf8:
     2186  stage: test
     2187  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     2188  variables:
     2189    CC: gcc-6
     2190    CXX: g++-6
     2191    LD: gcc-6
     2192    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     2193    LDFLAGS: ''
     2194  script: env; rake --verbose all test
     2195Test gcc-6 64bit_float_int64_word:
    15962196  stage: test
    15972197  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    16022202    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    16032203    LDFLAGS: ''
    1604   script: env; ./minirake --verbose all test
    1605 Test gcc-6 64bit_float_int64_utf8:
     2204  script: env; rake --verbose all test
     2205Test gcc-6 64bit_float_int64_word_utf8:
    16062206  stage: test
    16072207  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
     
    16122212    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    16132213    LDFLAGS: ''
    1614   script: env; ./minirake --verbose all test
     2214  script: env; rake --verbose all test
    16152215Test clang-3.5 32bit:
     2216  stage: test
     2217  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2218  variables:
     2219    CC: clang-3.5
     2220    CXX: clang++-3.5
     2221    LD: clang-3.5
     2222    CFLAGS: "-m32 "
     2223    LDFLAGS: "-m32"
     2224  script: env; rake --verbose all test
     2225Test clang-3.5 32bit_utf8:
     2226  stage: test
     2227  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2228  variables:
     2229    CC: clang-3.5
     2230    CXX: clang++-3.5
     2231    LD: clang-3.5
     2232    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     2233    LDFLAGS: "-m32"
     2234  script: env; rake --verbose all test
     2235Test clang-3.5 32bit_nan:
     2236  stage: test
     2237  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2238  variables:
     2239    CC: clang-3.5
     2240    CXX: clang++-3.5
     2241    LD: clang-3.5
     2242    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     2243    LDFLAGS: "-m32"
     2244  script: env; rake --verbose all test
     2245Test clang-3.5 32bit_nan_utf8:
     2246  stage: test
     2247  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2248  variables:
     2249    CC: clang-3.5
     2250    CXX: clang++-3.5
     2251    LD: clang-3.5
     2252    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     2253    LDFLAGS: "-m32"
     2254  script: env; rake --verbose all test
     2255Test clang-3.5 32bit_word:
    16162256  stage: test
    16172257  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    16222262    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    16232263    LDFLAGS: "-m32"
    1624   script: env; ./minirake --verbose all test
    1625 Test clang-3.5 32bit_utf8:
     2264  script: env; rake --verbose all test
     2265Test clang-3.5 32bit_word_utf8:
    16262266  stage: test
    16272267  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    16322272    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    16332273    LDFLAGS: "-m32"
    1634   script: env; ./minirake --verbose all test
    1635 Test clang-3.5 32bit_nan:
    1636   stage: test
    1637   image: registry.gitlab.com/dabroz/mruby:clang35_0.7
    1638   variables:
    1639     CC: clang-3.5
    1640     CXX: clang++-3.5
    1641     LD: clang-3.5
    1642     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    1643     LDFLAGS: "-m32"
    1644   script: env; ./minirake --verbose all test
    1645 Test clang-3.5 32bit_nan_utf8:
    1646   stage: test
    1647   image: registry.gitlab.com/dabroz/mruby:clang35_0.7
    1648   variables:
    1649     CC: clang-3.5
    1650     CXX: clang++-3.5
    1651     LD: clang-3.5
    1652     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    1653     LDFLAGS: "-m32"
    1654   script: env; ./minirake --verbose all test
     2274  script: env; rake --verbose all test
    16552275Test clang-3.5 32bit_int16:
    16562276  stage: test
     
    16622282    CFLAGS: "-m32 -DMRB_INT16=1"
    16632283    LDFLAGS: "-m32"
    1664   script: env; ./minirake --verbose all test
     2284  script: env; rake --verbose all test
    16652285Test clang-3.5 32bit_int16_utf8:
    16662286  stage: test
     
    16722292    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    16732293    LDFLAGS: "-m32"
    1674   script: env; ./minirake --verbose all test
     2294  script: env; rake --verbose all test
    16752295Test clang-3.5 32bit_int16_nan:
    16762296  stage: test
     
    16822302    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    16832303    LDFLAGS: "-m32"
    1684   script: env; ./minirake --verbose all test
     2304  script: env; rake --verbose all test
    16852305Test clang-3.5 32bit_int16_nan_utf8:
    16862306  stage: test
     
    16922312    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    16932313    LDFLAGS: "-m32"
    1694   script: env; ./minirake --verbose all test
     2314  script: env; rake --verbose all test
    16952315Test clang-3.5 32bit_int64:
    16962316  stage: test
     
    17022322    CFLAGS: "-m32 -DMRB_INT64=1"
    17032323    LDFLAGS: "-m32"
    1704   script: env; ./minirake --verbose all test
     2324  script: env; rake --verbose all test
    17052325Test clang-3.5 32bit_int64_utf8:
    17062326  stage: test
     
    17122332    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    17132333    LDFLAGS: "-m32"
    1714   script: env; ./minirake --verbose all test
     2334  script: env; rake --verbose all test
    17152335Test clang-3.5 32bit_float:
     2336  stage: test
     2337  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2338  variables:
     2339    CC: clang-3.5
     2340    CXX: clang++-3.5
     2341    LD: clang-3.5
     2342    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     2343    LDFLAGS: "-m32"
     2344  script: env; rake --verbose all test
     2345Test clang-3.5 32bit_float_utf8:
     2346  stage: test
     2347  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2348  variables:
     2349    CC: clang-3.5
     2350    CXX: clang++-3.5
     2351    LD: clang-3.5
     2352    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     2353    LDFLAGS: "-m32"
     2354  script: env; rake --verbose all test
     2355Test clang-3.5 32bit_float_word:
    17162356  stage: test
    17172357  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    17222362    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    17232363    LDFLAGS: "-m32"
    1724   script: env; ./minirake --verbose all test
    1725 Test clang-3.5 32bit_float_utf8:
     2364  script: env; rake --verbose all test
     2365Test clang-3.5 32bit_float_word_utf8:
    17262366  stage: test
    17272367  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    17322372    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    17332373    LDFLAGS: "-m32"
    1734   script: env; ./minirake --verbose all test
     2374  script: env; rake --verbose all test
    17352375Test clang-3.5 32bit_float_int16:
    17362376  stage: test
     
    17422382    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    17432383    LDFLAGS: "-m32"
    1744   script: env; ./minirake --verbose all test
     2384  script: env; rake --verbose all test
    17452385Test clang-3.5 32bit_float_int16_utf8:
    17462386  stage: test
     
    17522392    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    17532393    LDFLAGS: "-m32"
    1754   script: env; ./minirake --verbose all test
     2394  script: env; rake --verbose all test
    17552395Test clang-3.5 32bit_float_int64:
    17562396  stage: test
     
    17622402    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    17632403    LDFLAGS: "-m32"
    1764   script: env; ./minirake --verbose all test
     2404  script: env; rake --verbose all test
    17652405Test clang-3.5 32bit_float_int64_utf8:
    17662406  stage: test
     
    17722412    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    17732413    LDFLAGS: "-m32"
    1774   script: env; ./minirake --verbose all test
     2414  script: env; rake --verbose all test
    17752415Test clang-3.5 64bit:
     2416  stage: test
     2417  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2418  variables:
     2419    CC: clang-3.5
     2420    CXX: clang++-3.5
     2421    LD: clang-3.5
     2422    CFLAGS: ''
     2423    LDFLAGS: ''
     2424  script: env; rake --verbose all test
     2425Test clang-3.5 64bit_utf8:
     2426  stage: test
     2427  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2428  variables:
     2429    CC: clang-3.5
     2430    CXX: clang++-3.5
     2431    LD: clang-3.5
     2432    CFLAGS: "-DMRB_UTF8_STRING=1"
     2433    LDFLAGS: ''
     2434  script: env; rake --verbose all test
     2435Test clang-3.5 64bit_nan:
     2436  stage: test
     2437  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2438  variables:
     2439    CC: clang-3.5
     2440    CXX: clang++-3.5
     2441    LD: clang-3.5
     2442    CFLAGS: "-DMRB_NAN_BOXING=1"
     2443    LDFLAGS: ''
     2444  script: env; rake --verbose all test
     2445Test clang-3.5 64bit_nan_utf8:
     2446  stage: test
     2447  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2448  variables:
     2449    CC: clang-3.5
     2450    CXX: clang++-3.5
     2451    LD: clang-3.5
     2452    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     2453    LDFLAGS: ''
     2454  script: env; rake --verbose all test
     2455Test clang-3.5 64bit_word:
    17762456  stage: test
    17772457  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    17822462    CFLAGS: "-DMRB_WORD_BOXING=1"
    17832463    LDFLAGS: ''
    1784   script: env; ./minirake --verbose all test
    1785 Test clang-3.5 64bit_utf8:
     2464  script: env; rake --verbose all test
     2465Test clang-3.5 64bit_word_utf8:
    17862466  stage: test
    17872467  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    17922472    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    17932473    LDFLAGS: ''
    1794   script: env; ./minirake --verbose all test
    1795 Test clang-3.5 64bit_nan:
    1796   stage: test
    1797   image: registry.gitlab.com/dabroz/mruby:clang35_0.7
    1798   variables:
    1799     CC: clang-3.5
    1800     CXX: clang++-3.5
    1801     LD: clang-3.5
    1802     CFLAGS: "-DMRB_NAN_BOXING=1"
    1803     LDFLAGS: ''
    1804   script: env; ./minirake --verbose all test
    1805 Test clang-3.5 64bit_nan_utf8:
    1806   stage: test
    1807   image: registry.gitlab.com/dabroz/mruby:clang35_0.7
    1808   variables:
    1809     CC: clang-3.5
    1810     CXX: clang++-3.5
    1811     LD: clang-3.5
    1812     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    1813     LDFLAGS: ''
    1814   script: env; ./minirake --verbose all test
     2474  script: env; rake --verbose all test
    18152475Test clang-3.5 64bit_int16:
    18162476  stage: test
     
    18222482    CFLAGS: "-DMRB_INT16=1"
    18232483    LDFLAGS: ''
    1824   script: env; ./minirake --verbose all test
     2484  script: env; rake --verbose all test
    18252485Test clang-3.5 64bit_int16_utf8:
    18262486  stage: test
     
    18322492    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    18332493    LDFLAGS: ''
    1834   script: env; ./minirake --verbose all test
     2494  script: env; rake --verbose all test
    18352495Test clang-3.5 64bit_int16_nan:
    18362496  stage: test
     
    18422502    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    18432503    LDFLAGS: ''
    1844   script: env; ./minirake --verbose all test
     2504  script: env; rake --verbose all test
    18452505Test clang-3.5 64bit_int16_nan_utf8:
    18462506  stage: test
     
    18522512    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    18532513    LDFLAGS: ''
    1854   script: env; ./minirake --verbose all test
     2514  script: env; rake --verbose all test
    18552515Test clang-3.5 64bit_int64:
     2516  stage: test
     2517  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2518  variables:
     2519    CC: clang-3.5
     2520    CXX: clang++-3.5
     2521    LD: clang-3.5
     2522    CFLAGS: "-DMRB_INT64=1"
     2523    LDFLAGS: ''
     2524  script: env; rake --verbose all test
     2525Test clang-3.5 64bit_int64_utf8:
     2526  stage: test
     2527  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2528  variables:
     2529    CC: clang-3.5
     2530    CXX: clang++-3.5
     2531    LD: clang-3.5
     2532    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     2533    LDFLAGS: ''
     2534  script: env; rake --verbose all test
     2535Test clang-3.5 64bit_int64_word:
    18562536  stage: test
    18572537  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    18622542    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    18632543    LDFLAGS: ''
    1864   script: env; ./minirake --verbose all test
    1865 Test clang-3.5 64bit_int64_utf8:
     2544  script: env; rake --verbose all test
     2545Test clang-3.5 64bit_int64_word_utf8:
    18662546  stage: test
    18672547  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    18722552    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    18732553    LDFLAGS: ''
    1874   script: env; ./minirake --verbose all test
     2554  script: env; rake --verbose all test
    18752555Test clang-3.5 64bit_float:
     2556  stage: test
     2557  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2558  variables:
     2559    CC: clang-3.5
     2560    CXX: clang++-3.5
     2561    LD: clang-3.5
     2562    CFLAGS: "-DMRB_USE_FLOAT=1"
     2563    LDFLAGS: ''
     2564  script: env; rake --verbose all test
     2565Test clang-3.5 64bit_float_utf8:
     2566  stage: test
     2567  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2568  variables:
     2569    CC: clang-3.5
     2570    CXX: clang++-3.5
     2571    LD: clang-3.5
     2572    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     2573    LDFLAGS: ''
     2574  script: env; rake --verbose all test
     2575Test clang-3.5 64bit_float_word:
    18762576  stage: test
    18772577  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    18822582    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    18832583    LDFLAGS: ''
    1884   script: env; ./minirake --verbose all test
    1885 Test clang-3.5 64bit_float_utf8:
     2584  script: env; rake --verbose all test
     2585Test clang-3.5 64bit_float_word_utf8:
    18862586  stage: test
    18872587  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    18922592    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    18932593    LDFLAGS: ''
    1894   script: env; ./minirake --verbose all test
     2594  script: env; rake --verbose all test
    18952595Test clang-3.5 64bit_float_int16:
    18962596  stage: test
     
    19022602    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    19032603    LDFLAGS: ''
    1904   script: env; ./minirake --verbose all test
     2604  script: env; rake --verbose all test
    19052605Test clang-3.5 64bit_float_int16_utf8:
    19062606  stage: test
     
    19122612    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    19132613    LDFLAGS: ''
    1914   script: env; ./minirake --verbose all test
     2614  script: env; rake --verbose all test
    19152615Test clang-3.5 64bit_float_int64:
     2616  stage: test
     2617  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2618  variables:
     2619    CC: clang-3.5
     2620    CXX: clang++-3.5
     2621    LD: clang-3.5
     2622    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     2623    LDFLAGS: ''
     2624  script: env; rake --verbose all test
     2625Test clang-3.5 64bit_float_int64_utf8:
     2626  stage: test
     2627  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     2628  variables:
     2629    CC: clang-3.5
     2630    CXX: clang++-3.5
     2631    LD: clang-3.5
     2632    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     2633    LDFLAGS: ''
     2634  script: env; rake --verbose all test
     2635Test clang-3.5 64bit_float_int64_word:
    19162636  stage: test
    19172637  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    19222642    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    19232643    LDFLAGS: ''
    1924   script: env; ./minirake --verbose all test
    1925 Test clang-3.5 64bit_float_int64_utf8:
     2644  script: env; rake --verbose all test
     2645Test clang-3.5 64bit_float_int64_word_utf8:
    19262646  stage: test
    19272647  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
     
    19322652    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    19332653    LDFLAGS: ''
    1934   script: env; ./minirake --verbose all test
     2654  script: env; rake --verbose all test
    19352655Test clang-3.6 32bit:
     2656  stage: test
     2657  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2658  variables:
     2659    CC: clang-3.6
     2660    CXX: clang++-3.6
     2661    LD: clang-3.6
     2662    CFLAGS: "-m32 "
     2663    LDFLAGS: "-m32"
     2664  script: env; rake --verbose all test
     2665Test clang-3.6 32bit_utf8:
     2666  stage: test
     2667  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2668  variables:
     2669    CC: clang-3.6
     2670    CXX: clang++-3.6
     2671    LD: clang-3.6
     2672    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     2673    LDFLAGS: "-m32"
     2674  script: env; rake --verbose all test
     2675Test clang-3.6 32bit_nan:
     2676  stage: test
     2677  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2678  variables:
     2679    CC: clang-3.6
     2680    CXX: clang++-3.6
     2681    LD: clang-3.6
     2682    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     2683    LDFLAGS: "-m32"
     2684  script: env; rake --verbose all test
     2685Test clang-3.6 32bit_nan_utf8:
     2686  stage: test
     2687  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2688  variables:
     2689    CC: clang-3.6
     2690    CXX: clang++-3.6
     2691    LD: clang-3.6
     2692    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     2693    LDFLAGS: "-m32"
     2694  script: env; rake --verbose all test
     2695Test clang-3.6 32bit_word:
    19362696  stage: test
    19372697  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    19422702    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    19432703    LDFLAGS: "-m32"
    1944   script: env; ./minirake --verbose all test
    1945 Test clang-3.6 32bit_utf8:
     2704  script: env; rake --verbose all test
     2705Test clang-3.6 32bit_word_utf8:
    19462706  stage: test
    19472707  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    19522712    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    19532713    LDFLAGS: "-m32"
    1954   script: env; ./minirake --verbose all test
    1955 Test clang-3.6 32bit_nan:
    1956   stage: test
    1957   image: registry.gitlab.com/dabroz/mruby:clang36_0.7
    1958   variables:
    1959     CC: clang-3.6
    1960     CXX: clang++-3.6
    1961     LD: clang-3.6
    1962     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    1963     LDFLAGS: "-m32"
    1964   script: env; ./minirake --verbose all test
    1965 Test clang-3.6 32bit_nan_utf8:
    1966   stage: test
    1967   image: registry.gitlab.com/dabroz/mruby:clang36_0.7
    1968   variables:
    1969     CC: clang-3.6
    1970     CXX: clang++-3.6
    1971     LD: clang-3.6
    1972     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    1973     LDFLAGS: "-m32"
    1974   script: env; ./minirake --verbose all test
     2714  script: env; rake --verbose all test
    19752715Test clang-3.6 32bit_int16:
    19762716  stage: test
     
    19822722    CFLAGS: "-m32 -DMRB_INT16=1"
    19832723    LDFLAGS: "-m32"
    1984   script: env; ./minirake --verbose all test
     2724  script: env; rake --verbose all test
    19852725Test clang-3.6 32bit_int16_utf8:
    19862726  stage: test
     
    19922732    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    19932733    LDFLAGS: "-m32"
    1994   script: env; ./minirake --verbose all test
     2734  script: env; rake --verbose all test
    19952735Test clang-3.6 32bit_int16_nan:
    19962736  stage: test
     
    20022742    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    20032743    LDFLAGS: "-m32"
    2004   script: env; ./minirake --verbose all test
     2744  script: env; rake --verbose all test
    20052745Test clang-3.6 32bit_int16_nan_utf8:
    20062746  stage: test
     
    20122752    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    20132753    LDFLAGS: "-m32"
    2014   script: env; ./minirake --verbose all test
     2754  script: env; rake --verbose all test
    20152755Test clang-3.6 32bit_int64:
    20162756  stage: test
     
    20222762    CFLAGS: "-m32 -DMRB_INT64=1"
    20232763    LDFLAGS: "-m32"
    2024   script: env; ./minirake --verbose all test
     2764  script: env; rake --verbose all test
    20252765Test clang-3.6 32bit_int64_utf8:
    20262766  stage: test
     
    20322772    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    20332773    LDFLAGS: "-m32"
    2034   script: env; ./minirake --verbose all test
     2774  script: env; rake --verbose all test
    20352775Test clang-3.6 32bit_float:
     2776  stage: test
     2777  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2778  variables:
     2779    CC: clang-3.6
     2780    CXX: clang++-3.6
     2781    LD: clang-3.6
     2782    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     2783    LDFLAGS: "-m32"
     2784  script: env; rake --verbose all test
     2785Test clang-3.6 32bit_float_utf8:
     2786  stage: test
     2787  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2788  variables:
     2789    CC: clang-3.6
     2790    CXX: clang++-3.6
     2791    LD: clang-3.6
     2792    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     2793    LDFLAGS: "-m32"
     2794  script: env; rake --verbose all test
     2795Test clang-3.6 32bit_float_word:
    20362796  stage: test
    20372797  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    20422802    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    20432803    LDFLAGS: "-m32"
    2044   script: env; ./minirake --verbose all test
    2045 Test clang-3.6 32bit_float_utf8:
     2804  script: env; rake --verbose all test
     2805Test clang-3.6 32bit_float_word_utf8:
    20462806  stage: test
    20472807  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    20522812    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    20532813    LDFLAGS: "-m32"
    2054   script: env; ./minirake --verbose all test
     2814  script: env; rake --verbose all test
    20552815Test clang-3.6 32bit_float_int16:
    20562816  stage: test
     
    20622822    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    20632823    LDFLAGS: "-m32"
    2064   script: env; ./minirake --verbose all test
     2824  script: env; rake --verbose all test
    20652825Test clang-3.6 32bit_float_int16_utf8:
    20662826  stage: test
     
    20722832    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    20732833    LDFLAGS: "-m32"
    2074   script: env; ./minirake --verbose all test
     2834  script: env; rake --verbose all test
    20752835Test clang-3.6 32bit_float_int64:
    20762836  stage: test
     
    20822842    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    20832843    LDFLAGS: "-m32"
    2084   script: env; ./minirake --verbose all test
     2844  script: env; rake --verbose all test
    20852845Test clang-3.6 32bit_float_int64_utf8:
    20862846  stage: test
     
    20922852    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    20932853    LDFLAGS: "-m32"
    2094   script: env; ./minirake --verbose all test
     2854  script: env; rake --verbose all test
    20952855Test clang-3.6 64bit:
     2856  stage: test
     2857  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2858  variables:
     2859    CC: clang-3.6
     2860    CXX: clang++-3.6
     2861    LD: clang-3.6
     2862    CFLAGS: ''
     2863    LDFLAGS: ''
     2864  script: env; rake --verbose all test
     2865Test clang-3.6 64bit_utf8:
     2866  stage: test
     2867  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2868  variables:
     2869    CC: clang-3.6
     2870    CXX: clang++-3.6
     2871    LD: clang-3.6
     2872    CFLAGS: "-DMRB_UTF8_STRING=1"
     2873    LDFLAGS: ''
     2874  script: env; rake --verbose all test
     2875Test clang-3.6 64bit_nan:
     2876  stage: test
     2877  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2878  variables:
     2879    CC: clang-3.6
     2880    CXX: clang++-3.6
     2881    LD: clang-3.6
     2882    CFLAGS: "-DMRB_NAN_BOXING=1"
     2883    LDFLAGS: ''
     2884  script: env; rake --verbose all test
     2885Test clang-3.6 64bit_nan_utf8:
     2886  stage: test
     2887  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2888  variables:
     2889    CC: clang-3.6
     2890    CXX: clang++-3.6
     2891    LD: clang-3.6
     2892    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     2893    LDFLAGS: ''
     2894  script: env; rake --verbose all test
     2895Test clang-3.6 64bit_word:
    20962896  stage: test
    20972897  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    21022902    CFLAGS: "-DMRB_WORD_BOXING=1"
    21032903    LDFLAGS: ''
    2104   script: env; ./minirake --verbose all test
    2105 Test clang-3.6 64bit_utf8:
     2904  script: env; rake --verbose all test
     2905Test clang-3.6 64bit_word_utf8:
    21062906  stage: test
    21072907  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    21122912    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    21132913    LDFLAGS: ''
    2114   script: env; ./minirake --verbose all test
    2115 Test clang-3.6 64bit_nan:
    2116   stage: test
    2117   image: registry.gitlab.com/dabroz/mruby:clang36_0.7
    2118   variables:
    2119     CC: clang-3.6
    2120     CXX: clang++-3.6
    2121     LD: clang-3.6
    2122     CFLAGS: "-DMRB_NAN_BOXING=1"
    2123     LDFLAGS: ''
    2124   script: env; ./minirake --verbose all test
    2125 Test clang-3.6 64bit_nan_utf8:
    2126   stage: test
    2127   image: registry.gitlab.com/dabroz/mruby:clang36_0.7
    2128   variables:
    2129     CC: clang-3.6
    2130     CXX: clang++-3.6
    2131     LD: clang-3.6
    2132     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    2133     LDFLAGS: ''
    2134   script: env; ./minirake --verbose all test
     2914  script: env; rake --verbose all test
    21352915Test clang-3.6 64bit_int16:
    21362916  stage: test
     
    21422922    CFLAGS: "-DMRB_INT16=1"
    21432923    LDFLAGS: ''
    2144   script: env; ./minirake --verbose all test
     2924  script: env; rake --verbose all test
    21452925Test clang-3.6 64bit_int16_utf8:
    21462926  stage: test
     
    21522932    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    21532933    LDFLAGS: ''
    2154   script: env; ./minirake --verbose all test
     2934  script: env; rake --verbose all test
    21552935Test clang-3.6 64bit_int16_nan:
    21562936  stage: test
     
    21622942    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    21632943    LDFLAGS: ''
    2164   script: env; ./minirake --verbose all test
     2944  script: env; rake --verbose all test
    21652945Test clang-3.6 64bit_int16_nan_utf8:
    21662946  stage: test
     
    21722952    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    21732953    LDFLAGS: ''
    2174   script: env; ./minirake --verbose all test
     2954  script: env; rake --verbose all test
    21752955Test clang-3.6 64bit_int64:
     2956  stage: test
     2957  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2958  variables:
     2959    CC: clang-3.6
     2960    CXX: clang++-3.6
     2961    LD: clang-3.6
     2962    CFLAGS: "-DMRB_INT64=1"
     2963    LDFLAGS: ''
     2964  script: env; rake --verbose all test
     2965Test clang-3.6 64bit_int64_utf8:
     2966  stage: test
     2967  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2968  variables:
     2969    CC: clang-3.6
     2970    CXX: clang++-3.6
     2971    LD: clang-3.6
     2972    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     2973    LDFLAGS: ''
     2974  script: env; rake --verbose all test
     2975Test clang-3.6 64bit_int64_word:
    21762976  stage: test
    21772977  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    21822982    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    21832983    LDFLAGS: ''
    2184   script: env; ./minirake --verbose all test
    2185 Test clang-3.6 64bit_int64_utf8:
     2984  script: env; rake --verbose all test
     2985Test clang-3.6 64bit_int64_word_utf8:
    21862986  stage: test
    21872987  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    21922992    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    21932993    LDFLAGS: ''
    2194   script: env; ./minirake --verbose all test
     2994  script: env; rake --verbose all test
    21952995Test clang-3.6 64bit_float:
     2996  stage: test
     2997  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     2998  variables:
     2999    CC: clang-3.6
     3000    CXX: clang++-3.6
     3001    LD: clang-3.6
     3002    CFLAGS: "-DMRB_USE_FLOAT=1"
     3003    LDFLAGS: ''
     3004  script: env; rake --verbose all test
     3005Test clang-3.6 64bit_float_utf8:
     3006  stage: test
     3007  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     3008  variables:
     3009    CC: clang-3.6
     3010    CXX: clang++-3.6
     3011    LD: clang-3.6
     3012    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     3013    LDFLAGS: ''
     3014  script: env; rake --verbose all test
     3015Test clang-3.6 64bit_float_word:
    21963016  stage: test
    21973017  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    22023022    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    22033023    LDFLAGS: ''
    2204   script: env; ./minirake --verbose all test
    2205 Test clang-3.6 64bit_float_utf8:
     3024  script: env; rake --verbose all test
     3025Test clang-3.6 64bit_float_word_utf8:
    22063026  stage: test
    22073027  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    22123032    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    22133033    LDFLAGS: ''
    2214   script: env; ./minirake --verbose all test
     3034  script: env; rake --verbose all test
    22153035Test clang-3.6 64bit_float_int16:
    22163036  stage: test
     
    22223042    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    22233043    LDFLAGS: ''
    2224   script: env; ./minirake --verbose all test
     3044  script: env; rake --verbose all test
    22253045Test clang-3.6 64bit_float_int16_utf8:
    22263046  stage: test
     
    22323052    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    22333053    LDFLAGS: ''
    2234   script: env; ./minirake --verbose all test
     3054  script: env; rake --verbose all test
    22353055Test clang-3.6 64bit_float_int64:
     3056  stage: test
     3057  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     3058  variables:
     3059    CC: clang-3.6
     3060    CXX: clang++-3.6
     3061    LD: clang-3.6
     3062    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     3063    LDFLAGS: ''
     3064  script: env; rake --verbose all test
     3065Test clang-3.6 64bit_float_int64_utf8:
     3066  stage: test
     3067  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     3068  variables:
     3069    CC: clang-3.6
     3070    CXX: clang++-3.6
     3071    LD: clang-3.6
     3072    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     3073    LDFLAGS: ''
     3074  script: env; rake --verbose all test
     3075Test clang-3.6 64bit_float_int64_word:
    22363076  stage: test
    22373077  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    22423082    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    22433083    LDFLAGS: ''
    2244   script: env; ./minirake --verbose all test
    2245 Test clang-3.6 64bit_float_int64_utf8:
     3084  script: env; rake --verbose all test
     3085Test clang-3.6 64bit_float_int64_word_utf8:
    22463086  stage: test
    22473087  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
     
    22523092    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    22533093    LDFLAGS: ''
    2254   script: env; ./minirake --verbose all test
     3094  script: env; rake --verbose all test
    22553095Test clang-3.7 32bit:
     3096  stage: test
     3097  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3098  variables:
     3099    CC: clang-3.7
     3100    CXX: clang++-3.7
     3101    LD: clang-3.7
     3102    CFLAGS: "-m32 "
     3103    LDFLAGS: "-m32"
     3104  script: env; rake --verbose all test
     3105Test clang-3.7 32bit_utf8:
     3106  stage: test
     3107  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3108  variables:
     3109    CC: clang-3.7
     3110    CXX: clang++-3.7
     3111    LD: clang-3.7
     3112    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     3113    LDFLAGS: "-m32"
     3114  script: env; rake --verbose all test
     3115Test clang-3.7 32bit_nan:
     3116  stage: test
     3117  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3118  variables:
     3119    CC: clang-3.7
     3120    CXX: clang++-3.7
     3121    LD: clang-3.7
     3122    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     3123    LDFLAGS: "-m32"
     3124  script: env; rake --verbose all test
     3125Test clang-3.7 32bit_nan_utf8:
     3126  stage: test
     3127  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3128  variables:
     3129    CC: clang-3.7
     3130    CXX: clang++-3.7
     3131    LD: clang-3.7
     3132    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     3133    LDFLAGS: "-m32"
     3134  script: env; rake --verbose all test
     3135Test clang-3.7 32bit_word:
    22563136  stage: test
    22573137  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    22623142    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    22633143    LDFLAGS: "-m32"
    2264   script: env; ./minirake --verbose all test
    2265 Test clang-3.7 32bit_utf8:
     3144  script: env; rake --verbose all test
     3145Test clang-3.7 32bit_word_utf8:
    22663146  stage: test
    22673147  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    22723152    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    22733153    LDFLAGS: "-m32"
    2274   script: env; ./minirake --verbose all test
    2275 Test clang-3.7 32bit_nan:
    2276   stage: test
    2277   image: registry.gitlab.com/dabroz/mruby:clang37_0.7
    2278   variables:
    2279     CC: clang-3.7
    2280     CXX: clang++-3.7
    2281     LD: clang-3.7
    2282     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    2283     LDFLAGS: "-m32"
    2284   script: env; ./minirake --verbose all test
    2285 Test clang-3.7 32bit_nan_utf8:
    2286   stage: test
    2287   image: registry.gitlab.com/dabroz/mruby:clang37_0.7
    2288   variables:
    2289     CC: clang-3.7
    2290     CXX: clang++-3.7
    2291     LD: clang-3.7
    2292     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    2293     LDFLAGS: "-m32"
    2294   script: env; ./minirake --verbose all test
     3154  script: env; rake --verbose all test
    22953155Test clang-3.7 32bit_int16:
    22963156  stage: test
     
    23023162    CFLAGS: "-m32 -DMRB_INT16=1"
    23033163    LDFLAGS: "-m32"
    2304   script: env; ./minirake --verbose all test
     3164  script: env; rake --verbose all test
    23053165Test clang-3.7 32bit_int16_utf8:
    23063166  stage: test
     
    23123172    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    23133173    LDFLAGS: "-m32"
    2314   script: env; ./minirake --verbose all test
     3174  script: env; rake --verbose all test
    23153175Test clang-3.7 32bit_int16_nan:
    23163176  stage: test
     
    23223182    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    23233183    LDFLAGS: "-m32"
    2324   script: env; ./minirake --verbose all test
     3184  script: env; rake --verbose all test
    23253185Test clang-3.7 32bit_int16_nan_utf8:
    23263186  stage: test
     
    23323192    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    23333193    LDFLAGS: "-m32"
    2334   script: env; ./minirake --verbose all test
     3194  script: env; rake --verbose all test
    23353195Test clang-3.7 32bit_int64:
    23363196  stage: test
     
    23423202    CFLAGS: "-m32 -DMRB_INT64=1"
    23433203    LDFLAGS: "-m32"
    2344   script: env; ./minirake --verbose all test
     3204  script: env; rake --verbose all test
    23453205Test clang-3.7 32bit_int64_utf8:
    23463206  stage: test
     
    23523212    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    23533213    LDFLAGS: "-m32"
    2354   script: env; ./minirake --verbose all test
     3214  script: env; rake --verbose all test
    23553215Test clang-3.7 32bit_float:
     3216  stage: test
     3217  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3218  variables:
     3219    CC: clang-3.7
     3220    CXX: clang++-3.7
     3221    LD: clang-3.7
     3222    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     3223    LDFLAGS: "-m32"
     3224  script: env; rake --verbose all test
     3225Test clang-3.7 32bit_float_utf8:
     3226  stage: test
     3227  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3228  variables:
     3229    CC: clang-3.7
     3230    CXX: clang++-3.7
     3231    LD: clang-3.7
     3232    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     3233    LDFLAGS: "-m32"
     3234  script: env; rake --verbose all test
     3235Test clang-3.7 32bit_float_word:
    23563236  stage: test
    23573237  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    23623242    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    23633243    LDFLAGS: "-m32"
    2364   script: env; ./minirake --verbose all test
    2365 Test clang-3.7 32bit_float_utf8:
     3244  script: env; rake --verbose all test
     3245Test clang-3.7 32bit_float_word_utf8:
    23663246  stage: test
    23673247  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    23723252    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    23733253    LDFLAGS: "-m32"
    2374   script: env; ./minirake --verbose all test
     3254  script: env; rake --verbose all test
    23753255Test clang-3.7 32bit_float_int16:
    23763256  stage: test
     
    23823262    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    23833263    LDFLAGS: "-m32"
    2384   script: env; ./minirake --verbose all test
     3264  script: env; rake --verbose all test
    23853265Test clang-3.7 32bit_float_int16_utf8:
    23863266  stage: test
     
    23923272    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    23933273    LDFLAGS: "-m32"
    2394   script: env; ./minirake --verbose all test
     3274  script: env; rake --verbose all test
    23953275Test clang-3.7 32bit_float_int64:
    23963276  stage: test
     
    24023282    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    24033283    LDFLAGS: "-m32"
    2404   script: env; ./minirake --verbose all test
     3284  script: env; rake --verbose all test
    24053285Test clang-3.7 32bit_float_int64_utf8:
    24063286  stage: test
     
    24123292    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    24133293    LDFLAGS: "-m32"
    2414   script: env; ./minirake --verbose all test
     3294  script: env; rake --verbose all test
    24153295Test clang-3.7 64bit:
     3296  stage: test
     3297  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3298  variables:
     3299    CC: clang-3.7
     3300    CXX: clang++-3.7
     3301    LD: clang-3.7
     3302    CFLAGS: ''
     3303    LDFLAGS: ''
     3304  script: env; rake --verbose all test
     3305Test clang-3.7 64bit_utf8:
     3306  stage: test
     3307  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3308  variables:
     3309    CC: clang-3.7
     3310    CXX: clang++-3.7
     3311    LD: clang-3.7
     3312    CFLAGS: "-DMRB_UTF8_STRING=1"
     3313    LDFLAGS: ''
     3314  script: env; rake --verbose all test
     3315Test clang-3.7 64bit_nan:
     3316  stage: test
     3317  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3318  variables:
     3319    CC: clang-3.7
     3320    CXX: clang++-3.7
     3321    LD: clang-3.7
     3322    CFLAGS: "-DMRB_NAN_BOXING=1"
     3323    LDFLAGS: ''
     3324  script: env; rake --verbose all test
     3325Test clang-3.7 64bit_nan_utf8:
     3326  stage: test
     3327  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3328  variables:
     3329    CC: clang-3.7
     3330    CXX: clang++-3.7
     3331    LD: clang-3.7
     3332    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     3333    LDFLAGS: ''
     3334  script: env; rake --verbose all test
     3335Test clang-3.7 64bit_word:
    24163336  stage: test
    24173337  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    24223342    CFLAGS: "-DMRB_WORD_BOXING=1"
    24233343    LDFLAGS: ''
    2424   script: env; ./minirake --verbose all test
    2425 Test clang-3.7 64bit_utf8:
     3344  script: env; rake --verbose all test
     3345Test clang-3.7 64bit_word_utf8:
    24263346  stage: test
    24273347  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    24323352    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    24333353    LDFLAGS: ''
    2434   script: env; ./minirake --verbose all test
    2435 Test clang-3.7 64bit_nan:
    2436   stage: test
    2437   image: registry.gitlab.com/dabroz/mruby:clang37_0.7
    2438   variables:
    2439     CC: clang-3.7
    2440     CXX: clang++-3.7
    2441     LD: clang-3.7
    2442     CFLAGS: "-DMRB_NAN_BOXING=1"
    2443     LDFLAGS: ''
    2444   script: env; ./minirake --verbose all test
    2445 Test clang-3.7 64bit_nan_utf8:
    2446   stage: test
    2447   image: registry.gitlab.com/dabroz/mruby:clang37_0.7
    2448   variables:
    2449     CC: clang-3.7
    2450     CXX: clang++-3.7
    2451     LD: clang-3.7
    2452     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    2453     LDFLAGS: ''
    2454   script: env; ./minirake --verbose all test
     3354  script: env; rake --verbose all test
    24553355Test clang-3.7 64bit_int16:
    24563356  stage: test
     
    24623362    CFLAGS: "-DMRB_INT16=1"
    24633363    LDFLAGS: ''
    2464   script: env; ./minirake --verbose all test
     3364  script: env; rake --verbose all test
    24653365Test clang-3.7 64bit_int16_utf8:
    24663366  stage: test
     
    24723372    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    24733373    LDFLAGS: ''
    2474   script: env; ./minirake --verbose all test
     3374  script: env; rake --verbose all test
    24753375Test clang-3.7 64bit_int16_nan:
    24763376  stage: test
     
    24823382    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    24833383    LDFLAGS: ''
    2484   script: env; ./minirake --verbose all test
     3384  script: env; rake --verbose all test
    24853385Test clang-3.7 64bit_int16_nan_utf8:
    24863386  stage: test
     
    24923392    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    24933393    LDFLAGS: ''
    2494   script: env; ./minirake --verbose all test
     3394  script: env; rake --verbose all test
    24953395Test clang-3.7 64bit_int64:
     3396  stage: test
     3397  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3398  variables:
     3399    CC: clang-3.7
     3400    CXX: clang++-3.7
     3401    LD: clang-3.7
     3402    CFLAGS: "-DMRB_INT64=1"
     3403    LDFLAGS: ''
     3404  script: env; rake --verbose all test
     3405Test clang-3.7 64bit_int64_utf8:
     3406  stage: test
     3407  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3408  variables:
     3409    CC: clang-3.7
     3410    CXX: clang++-3.7
     3411    LD: clang-3.7
     3412    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     3413    LDFLAGS: ''
     3414  script: env; rake --verbose all test
     3415Test clang-3.7 64bit_int64_word:
    24963416  stage: test
    24973417  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    25023422    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    25033423    LDFLAGS: ''
    2504   script: env; ./minirake --verbose all test
    2505 Test clang-3.7 64bit_int64_utf8:
     3424  script: env; rake --verbose all test
     3425Test clang-3.7 64bit_int64_word_utf8:
    25063426  stage: test
    25073427  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    25123432    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    25133433    LDFLAGS: ''
    2514   script: env; ./minirake --verbose all test
     3434  script: env; rake --verbose all test
    25153435Test clang-3.7 64bit_float:
     3436  stage: test
     3437  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3438  variables:
     3439    CC: clang-3.7
     3440    CXX: clang++-3.7
     3441    LD: clang-3.7
     3442    CFLAGS: "-DMRB_USE_FLOAT=1"
     3443    LDFLAGS: ''
     3444  script: env; rake --verbose all test
     3445Test clang-3.7 64bit_float_utf8:
     3446  stage: test
     3447  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3448  variables:
     3449    CC: clang-3.7
     3450    CXX: clang++-3.7
     3451    LD: clang-3.7
     3452    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     3453    LDFLAGS: ''
     3454  script: env; rake --verbose all test
     3455Test clang-3.7 64bit_float_word:
    25163456  stage: test
    25173457  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    25223462    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    25233463    LDFLAGS: ''
    2524   script: env; ./minirake --verbose all test
    2525 Test clang-3.7 64bit_float_utf8:
     3464  script: env; rake --verbose all test
     3465Test clang-3.7 64bit_float_word_utf8:
    25263466  stage: test
    25273467  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    25323472    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    25333473    LDFLAGS: ''
    2534   script: env; ./minirake --verbose all test
     3474  script: env; rake --verbose all test
    25353475Test clang-3.7 64bit_float_int16:
    25363476  stage: test
     
    25423482    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    25433483    LDFLAGS: ''
    2544   script: env; ./minirake --verbose all test
     3484  script: env; rake --verbose all test
    25453485Test clang-3.7 64bit_float_int16_utf8:
    25463486  stage: test
     
    25523492    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    25533493    LDFLAGS: ''
    2554   script: env; ./minirake --verbose all test
     3494  script: env; rake --verbose all test
    25553495Test clang-3.7 64bit_float_int64:
     3496  stage: test
     3497  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3498  variables:
     3499    CC: clang-3.7
     3500    CXX: clang++-3.7
     3501    LD: clang-3.7
     3502    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     3503    LDFLAGS: ''
     3504  script: env; rake --verbose all test
     3505Test clang-3.7 64bit_float_int64_utf8:
     3506  stage: test
     3507  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     3508  variables:
     3509    CC: clang-3.7
     3510    CXX: clang++-3.7
     3511    LD: clang-3.7
     3512    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     3513    LDFLAGS: ''
     3514  script: env; rake --verbose all test
     3515Test clang-3.7 64bit_float_int64_word:
    25563516  stage: test
    25573517  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    25623522    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    25633523    LDFLAGS: ''
    2564   script: env; ./minirake --verbose all test
    2565 Test clang-3.7 64bit_float_int64_utf8:
     3524  script: env; rake --verbose all test
     3525Test clang-3.7 64bit_float_int64_word_utf8:
    25663526  stage: test
    25673527  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
     
    25723532    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    25733533    LDFLAGS: ''
    2574   script: env; ./minirake --verbose all test
     3534  script: env; rake --verbose all test
    25753535Test clang-3.8 32bit:
     3536  stage: test
     3537  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3538  variables:
     3539    CC: clang-3.8
     3540    CXX: clang++-3.8
     3541    LD: clang-3.8
     3542    CFLAGS: "-m32 "
     3543    LDFLAGS: "-m32"
     3544  script: env; rake --verbose all test
     3545Test clang-3.8 32bit_utf8:
     3546  stage: test
     3547  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3548  variables:
     3549    CC: clang-3.8
     3550    CXX: clang++-3.8
     3551    LD: clang-3.8
     3552    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     3553    LDFLAGS: "-m32"
     3554  script: env; rake --verbose all test
     3555Test clang-3.8 32bit_nan:
     3556  stage: test
     3557  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3558  variables:
     3559    CC: clang-3.8
     3560    CXX: clang++-3.8
     3561    LD: clang-3.8
     3562    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     3563    LDFLAGS: "-m32"
     3564  script: env; rake --verbose all test
     3565Test clang-3.8 32bit_nan_utf8:
     3566  stage: test
     3567  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3568  variables:
     3569    CC: clang-3.8
     3570    CXX: clang++-3.8
     3571    LD: clang-3.8
     3572    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     3573    LDFLAGS: "-m32"
     3574  script: env; rake --verbose all test
     3575Test clang-3.8 32bit_word:
    25763576  stage: test
    25773577  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    25823582    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    25833583    LDFLAGS: "-m32"
    2584   script: env; ./minirake --verbose all test
    2585 Test clang-3.8 32bit_utf8:
     3584  script: env; rake --verbose all test
     3585Test clang-3.8 32bit_word_utf8:
    25863586  stage: test
    25873587  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    25923592    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    25933593    LDFLAGS: "-m32"
    2594   script: env; ./minirake --verbose all test
    2595 Test clang-3.8 32bit_nan:
    2596   stage: test
    2597   image: registry.gitlab.com/dabroz/mruby:clang38_0.7
    2598   variables:
    2599     CC: clang-3.8
    2600     CXX: clang++-3.8
    2601     LD: clang-3.8
    2602     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    2603     LDFLAGS: "-m32"
    2604   script: env; ./minirake --verbose all test
    2605 Test clang-3.8 32bit_nan_utf8:
    2606   stage: test
    2607   image: registry.gitlab.com/dabroz/mruby:clang38_0.7
    2608   variables:
    2609     CC: clang-3.8
    2610     CXX: clang++-3.8
    2611     LD: clang-3.8
    2612     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    2613     LDFLAGS: "-m32"
    2614   script: env; ./minirake --verbose all test
     3594  script: env; rake --verbose all test
    26153595Test clang-3.8 32bit_int16:
    26163596  stage: test
     
    26223602    CFLAGS: "-m32 -DMRB_INT16=1"
    26233603    LDFLAGS: "-m32"
    2624   script: env; ./minirake --verbose all test
     3604  script: env; rake --verbose all test
    26253605Test clang-3.8 32bit_int16_utf8:
    26263606  stage: test
     
    26323612    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    26333613    LDFLAGS: "-m32"
    2634   script: env; ./minirake --verbose all test
     3614  script: env; rake --verbose all test
    26353615Test clang-3.8 32bit_int16_nan:
    26363616  stage: test
     
    26423622    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    26433623    LDFLAGS: "-m32"
    2644   script: env; ./minirake --verbose all test
     3624  script: env; rake --verbose all test
    26453625Test clang-3.8 32bit_int16_nan_utf8:
    26463626  stage: test
     
    26523632    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    26533633    LDFLAGS: "-m32"
    2654   script: env; ./minirake --verbose all test
     3634  script: env; rake --verbose all test
    26553635Test clang-3.8 32bit_int64:
    26563636  stage: test
     
    26623642    CFLAGS: "-m32 -DMRB_INT64=1"
    26633643    LDFLAGS: "-m32"
    2664   script: env; ./minirake --verbose all test
     3644  script: env; rake --verbose all test
    26653645Test clang-3.8 32bit_int64_utf8:
    26663646  stage: test
     
    26723652    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    26733653    LDFLAGS: "-m32"
    2674   script: env; ./minirake --verbose all test
     3654  script: env; rake --verbose all test
    26753655Test clang-3.8 32bit_float:
     3656  stage: test
     3657  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3658  variables:
     3659    CC: clang-3.8
     3660    CXX: clang++-3.8
     3661    LD: clang-3.8
     3662    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     3663    LDFLAGS: "-m32"
     3664  script: env; rake --verbose all test
     3665Test clang-3.8 32bit_float_utf8:
     3666  stage: test
     3667  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3668  variables:
     3669    CC: clang-3.8
     3670    CXX: clang++-3.8
     3671    LD: clang-3.8
     3672    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     3673    LDFLAGS: "-m32"
     3674  script: env; rake --verbose all test
     3675Test clang-3.8 32bit_float_word:
    26763676  stage: test
    26773677  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    26823682    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    26833683    LDFLAGS: "-m32"
    2684   script: env; ./minirake --verbose all test
    2685 Test clang-3.8 32bit_float_utf8:
     3684  script: env; rake --verbose all test
     3685Test clang-3.8 32bit_float_word_utf8:
    26863686  stage: test
    26873687  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    26923692    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    26933693    LDFLAGS: "-m32"
    2694   script: env; ./minirake --verbose all test
     3694  script: env; rake --verbose all test
    26953695Test clang-3.8 32bit_float_int16:
    26963696  stage: test
     
    27023702    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    27033703    LDFLAGS: "-m32"
    2704   script: env; ./minirake --verbose all test
     3704  script: env; rake --verbose all test
    27053705Test clang-3.8 32bit_float_int16_utf8:
    27063706  stage: test
     
    27123712    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    27133713    LDFLAGS: "-m32"
    2714   script: env; ./minirake --verbose all test
     3714  script: env; rake --verbose all test
    27153715Test clang-3.8 32bit_float_int64:
    27163716  stage: test
     
    27223722    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    27233723    LDFLAGS: "-m32"
    2724   script: env; ./minirake --verbose all test
     3724  script: env; rake --verbose all test
    27253725Test clang-3.8 32bit_float_int64_utf8:
    27263726  stage: test
     
    27323732    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    27333733    LDFLAGS: "-m32"
    2734   script: env; ./minirake --verbose all test
     3734  script: env; rake --verbose all test
    27353735Test clang-3.8 64bit:
     3736  stage: test
     3737  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3738  variables:
     3739    CC: clang-3.8
     3740    CXX: clang++-3.8
     3741    LD: clang-3.8
     3742    CFLAGS: ''
     3743    LDFLAGS: ''
     3744  script: env; rake --verbose all test
     3745Test clang-3.8 64bit_utf8:
     3746  stage: test
     3747  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3748  variables:
     3749    CC: clang-3.8
     3750    CXX: clang++-3.8
     3751    LD: clang-3.8
     3752    CFLAGS: "-DMRB_UTF8_STRING=1"
     3753    LDFLAGS: ''
     3754  script: env; rake --verbose all test
     3755Test clang-3.8 64bit_nan:
     3756  stage: test
     3757  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3758  variables:
     3759    CC: clang-3.8
     3760    CXX: clang++-3.8
     3761    LD: clang-3.8
     3762    CFLAGS: "-DMRB_NAN_BOXING=1"
     3763    LDFLAGS: ''
     3764  script: env; rake --verbose all test
     3765Test clang-3.8 64bit_nan_utf8:
     3766  stage: test
     3767  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3768  variables:
     3769    CC: clang-3.8
     3770    CXX: clang++-3.8
     3771    LD: clang-3.8
     3772    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     3773    LDFLAGS: ''
     3774  script: env; rake --verbose all test
     3775Test clang-3.8 64bit_word:
    27363776  stage: test
    27373777  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    27423782    CFLAGS: "-DMRB_WORD_BOXING=1"
    27433783    LDFLAGS: ''
    2744   script: env; ./minirake --verbose all test
    2745 Test clang-3.8 64bit_utf8:
     3784  script: env; rake --verbose all test
     3785Test clang-3.8 64bit_word_utf8:
    27463786  stage: test
    27473787  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    27523792    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    27533793    LDFLAGS: ''
    2754   script: env; ./minirake --verbose all test
    2755 Test clang-3.8 64bit_nan:
    2756   stage: test
    2757   image: registry.gitlab.com/dabroz/mruby:clang38_0.7
    2758   variables:
    2759     CC: clang-3.8
    2760     CXX: clang++-3.8
    2761     LD: clang-3.8
    2762     CFLAGS: "-DMRB_NAN_BOXING=1"
    2763     LDFLAGS: ''
    2764   script: env; ./minirake --verbose all test
    2765 Test clang-3.8 64bit_nan_utf8:
    2766   stage: test
    2767   image: registry.gitlab.com/dabroz/mruby:clang38_0.7
    2768   variables:
    2769     CC: clang-3.8
    2770     CXX: clang++-3.8
    2771     LD: clang-3.8
    2772     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    2773     LDFLAGS: ''
    2774   script: env; ./minirake --verbose all test
     3794  script: env; rake --verbose all test
    27753795Test clang-3.8 64bit_int16:
    27763796  stage: test
     
    27823802    CFLAGS: "-DMRB_INT16=1"
    27833803    LDFLAGS: ''
    2784   script: env; ./minirake --verbose all test
     3804  script: env; rake --verbose all test
    27853805Test clang-3.8 64bit_int16_utf8:
    27863806  stage: test
     
    27923812    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    27933813    LDFLAGS: ''
    2794   script: env; ./minirake --verbose all test
     3814  script: env; rake --verbose all test
    27953815Test clang-3.8 64bit_int16_nan:
    27963816  stage: test
     
    28023822    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    28033823    LDFLAGS: ''
    2804   script: env; ./minirake --verbose all test
     3824  script: env; rake --verbose all test
    28053825Test clang-3.8 64bit_int16_nan_utf8:
    28063826  stage: test
     
    28123832    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    28133833    LDFLAGS: ''
    2814   script: env; ./minirake --verbose all test
     3834  script: env; rake --verbose all test
    28153835Test clang-3.8 64bit_int64:
     3836  stage: test
     3837  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3838  variables:
     3839    CC: clang-3.8
     3840    CXX: clang++-3.8
     3841    LD: clang-3.8
     3842    CFLAGS: "-DMRB_INT64=1"
     3843    LDFLAGS: ''
     3844  script: env; rake --verbose all test
     3845Test clang-3.8 64bit_int64_utf8:
     3846  stage: test
     3847  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3848  variables:
     3849    CC: clang-3.8
     3850    CXX: clang++-3.8
     3851    LD: clang-3.8
     3852    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     3853    LDFLAGS: ''
     3854  script: env; rake --verbose all test
     3855Test clang-3.8 64bit_int64_word:
    28163856  stage: test
    28173857  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    28223862    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    28233863    LDFLAGS: ''
    2824   script: env; ./minirake --verbose all test
    2825 Test clang-3.8 64bit_int64_utf8:
     3864  script: env; rake --verbose all test
     3865Test clang-3.8 64bit_int64_word_utf8:
    28263866  stage: test
    28273867  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    28323872    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    28333873    LDFLAGS: ''
    2834   script: env; ./minirake --verbose all test
     3874  script: env; rake --verbose all test
    28353875Test clang-3.8 64bit_float:
     3876  stage: test
     3877  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3878  variables:
     3879    CC: clang-3.8
     3880    CXX: clang++-3.8
     3881    LD: clang-3.8
     3882    CFLAGS: "-DMRB_USE_FLOAT=1"
     3883    LDFLAGS: ''
     3884  script: env; rake --verbose all test
     3885Test clang-3.8 64bit_float_utf8:
     3886  stage: test
     3887  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3888  variables:
     3889    CC: clang-3.8
     3890    CXX: clang++-3.8
     3891    LD: clang-3.8
     3892    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     3893    LDFLAGS: ''
     3894  script: env; rake --verbose all test
     3895Test clang-3.8 64bit_float_word:
    28363896  stage: test
    28373897  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    28423902    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    28433903    LDFLAGS: ''
    2844   script: env; ./minirake --verbose all test
    2845 Test clang-3.8 64bit_float_utf8:
     3904  script: env; rake --verbose all test
     3905Test clang-3.8 64bit_float_word_utf8:
    28463906  stage: test
    28473907  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    28523912    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    28533913    LDFLAGS: ''
    2854   script: env; ./minirake --verbose all test
     3914  script: env; rake --verbose all test
    28553915Test clang-3.8 64bit_float_int16:
    28563916  stage: test
     
    28623922    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    28633923    LDFLAGS: ''
    2864   script: env; ./minirake --verbose all test
     3924  script: env; rake --verbose all test
    28653925Test clang-3.8 64bit_float_int16_utf8:
    28663926  stage: test
     
    28723932    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    28733933    LDFLAGS: ''
    2874   script: env; ./minirake --verbose all test
     3934  script: env; rake --verbose all test
    28753935Test clang-3.8 64bit_float_int64:
     3936  stage: test
     3937  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3938  variables:
     3939    CC: clang-3.8
     3940    CXX: clang++-3.8
     3941    LD: clang-3.8
     3942    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     3943    LDFLAGS: ''
     3944  script: env; rake --verbose all test
     3945Test clang-3.8 64bit_float_int64_utf8:
     3946  stage: test
     3947  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     3948  variables:
     3949    CC: clang-3.8
     3950    CXX: clang++-3.8
     3951    LD: clang-3.8
     3952    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     3953    LDFLAGS: ''
     3954  script: env; rake --verbose all test
     3955Test clang-3.8 64bit_float_int64_word:
    28763956  stage: test
    28773957  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    28823962    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    28833963    LDFLAGS: ''
    2884   script: env; ./minirake --verbose all test
    2885 Test clang-3.8 64bit_float_int64_utf8:
     3964  script: env; rake --verbose all test
     3965Test clang-3.8 64bit_float_int64_word_utf8:
    28863966  stage: test
    28873967  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
     
    28923972    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    28933973    LDFLAGS: ''
    2894   script: env; ./minirake --verbose all test
     3974  script: env; rake --verbose all test
    28953975Test clang-3.9 32bit:
     3976  stage: test
     3977  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     3978  variables:
     3979    CC: clang-3.9
     3980    CXX: clang++-3.9
     3981    LD: clang-3.9
     3982    CFLAGS: "-m32 "
     3983    LDFLAGS: "-m32"
     3984  script: env; rake --verbose all test
     3985Test clang-3.9 32bit_utf8:
     3986  stage: test
     3987  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     3988  variables:
     3989    CC: clang-3.9
     3990    CXX: clang++-3.9
     3991    LD: clang-3.9
     3992    CFLAGS: "-m32 -DMRB_UTF8_STRING=1"
     3993    LDFLAGS: "-m32"
     3994  script: env; rake --verbose all test
     3995Test clang-3.9 32bit_nan:
     3996  stage: test
     3997  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     3998  variables:
     3999    CC: clang-3.9
     4000    CXX: clang++-3.9
     4001    LD: clang-3.9
     4002    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
     4003    LDFLAGS: "-m32"
     4004  script: env; rake --verbose all test
     4005Test clang-3.9 32bit_nan_utf8:
     4006  stage: test
     4007  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4008  variables:
     4009    CC: clang-3.9
     4010    CXX: clang++-3.9
     4011    LD: clang-3.9
     4012    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     4013    LDFLAGS: "-m32"
     4014  script: env; rake --verbose all test
     4015Test clang-3.9 32bit_word:
    28964016  stage: test
    28974017  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    29024022    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
    29034023    LDFLAGS: "-m32"
    2904   script: env; ./minirake --verbose all test
    2905 Test clang-3.9 32bit_utf8:
     4024  script: env; rake --verbose all test
     4025Test clang-3.9 32bit_word_utf8:
    29064026  stage: test
    29074027  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    29124032    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    29134033    LDFLAGS: "-m32"
    2914   script: env; ./minirake --verbose all test
    2915 Test clang-3.9 32bit_nan:
    2916   stage: test
    2917   image: registry.gitlab.com/dabroz/mruby:clang39_0.7
    2918   variables:
    2919     CC: clang-3.9
    2920     CXX: clang++-3.9
    2921     LD: clang-3.9
    2922     CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
    2923     LDFLAGS: "-m32"
    2924   script: env; ./minirake --verbose all test
    2925 Test clang-3.9 32bit_nan_utf8:
    2926   stage: test
    2927   image: registry.gitlab.com/dabroz/mruby:clang39_0.7
    2928   variables:
    2929     CC: clang-3.9
    2930     CXX: clang++-3.9
    2931     LD: clang-3.9
    2932     CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    2933     LDFLAGS: "-m32"
    2934   script: env; ./minirake --verbose all test
     4034  script: env; rake --verbose all test
    29354035Test clang-3.9 32bit_int16:
    29364036  stage: test
     
    29424042    CFLAGS: "-m32 -DMRB_INT16=1"
    29434043    LDFLAGS: "-m32"
    2944   script: env; ./minirake --verbose all test
     4044  script: env; rake --verbose all test
    29454045Test clang-3.9 32bit_int16_utf8:
    29464046  stage: test
     
    29524052    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    29534053    LDFLAGS: "-m32"
    2954   script: env; ./minirake --verbose all test
     4054  script: env; rake --verbose all test
    29554055Test clang-3.9 32bit_int16_nan:
    29564056  stage: test
     
    29624062    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    29634063    LDFLAGS: "-m32"
    2964   script: env; ./minirake --verbose all test
     4064  script: env; rake --verbose all test
    29654065Test clang-3.9 32bit_int16_nan_utf8:
    29664066  stage: test
     
    29724072    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    29734073    LDFLAGS: "-m32"
    2974   script: env; ./minirake --verbose all test
     4074  script: env; rake --verbose all test
    29754075Test clang-3.9 32bit_int64:
    29764076  stage: test
     
    29824082    CFLAGS: "-m32 -DMRB_INT64=1"
    29834083    LDFLAGS: "-m32"
    2984   script: env; ./minirake --verbose all test
     4084  script: env; rake --verbose all test
    29854085Test clang-3.9 32bit_int64_utf8:
    29864086  stage: test
     
    29924092    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    29934093    LDFLAGS: "-m32"
    2994   script: env; ./minirake --verbose all test
     4094  script: env; rake --verbose all test
    29954095Test clang-3.9 32bit_float:
     4096  stage: test
     4097  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4098  variables:
     4099    CC: clang-3.9
     4100    CXX: clang++-3.9
     4101    LD: clang-3.9
     4102    CFLAGS: "-m32 -DMRB_USE_FLOAT=1"
     4103    LDFLAGS: "-m32"
     4104  script: env; rake --verbose all test
     4105Test clang-3.9 32bit_float_utf8:
     4106  stage: test
     4107  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4108  variables:
     4109    CC: clang-3.9
     4110    CXX: clang++-3.9
     4111    LD: clang-3.9
     4112    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     4113    LDFLAGS: "-m32"
     4114  script: env; rake --verbose all test
     4115Test clang-3.9 32bit_float_word:
    29964116  stage: test
    29974117  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    30024122    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    30034123    LDFLAGS: "-m32"
    3004   script: env; ./minirake --verbose all test
    3005 Test clang-3.9 32bit_float_utf8:
     4124  script: env; rake --verbose all test
     4125Test clang-3.9 32bit_float_word_utf8:
    30064126  stage: test
    30074127  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    30124132    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    30134133    LDFLAGS: "-m32"
    3014   script: env; ./minirake --verbose all test
     4134  script: env; rake --verbose all test
    30154135Test clang-3.9 32bit_float_int16:
    30164136  stage: test
     
    30224142    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    30234143    LDFLAGS: "-m32"
    3024   script: env; ./minirake --verbose all test
     4144  script: env; rake --verbose all test
    30254145Test clang-3.9 32bit_float_int16_utf8:
    30264146  stage: test
     
    30324152    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    30334153    LDFLAGS: "-m32"
    3034   script: env; ./minirake --verbose all test
     4154  script: env; rake --verbose all test
    30354155Test clang-3.9 32bit_float_int64:
    30364156  stage: test
     
    30424162    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
    30434163    LDFLAGS: "-m32"
    3044   script: env; ./minirake --verbose all test
     4164  script: env; rake --verbose all test
    30454165Test clang-3.9 32bit_float_int64_utf8:
    30464166  stage: test
     
    30524172    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
    30534173    LDFLAGS: "-m32"
    3054   script: env; ./minirake --verbose all test
     4174  script: env; rake --verbose all test
    30554175Test clang-3.9 64bit:
     4176  stage: test
     4177  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4178  variables:
     4179    CC: clang-3.9
     4180    CXX: clang++-3.9
     4181    LD: clang-3.9
     4182    CFLAGS: ''
     4183    LDFLAGS: ''
     4184  script: env; rake --verbose all test
     4185Test clang-3.9 64bit_utf8:
     4186  stage: test
     4187  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4188  variables:
     4189    CC: clang-3.9
     4190    CXX: clang++-3.9
     4191    LD: clang-3.9
     4192    CFLAGS: "-DMRB_UTF8_STRING=1"
     4193    LDFLAGS: ''
     4194  script: env; rake --verbose all test
     4195Test clang-3.9 64bit_nan:
     4196  stage: test
     4197  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4198  variables:
     4199    CC: clang-3.9
     4200    CXX: clang++-3.9
     4201    LD: clang-3.9
     4202    CFLAGS: "-DMRB_NAN_BOXING=1"
     4203    LDFLAGS: ''
     4204  script: env; rake --verbose all test
     4205Test clang-3.9 64bit_nan_utf8:
     4206  stage: test
     4207  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4208  variables:
     4209    CC: clang-3.9
     4210    CXX: clang++-3.9
     4211    LD: clang-3.9
     4212    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
     4213    LDFLAGS: ''
     4214  script: env; rake --verbose all test
     4215Test clang-3.9 64bit_word:
    30564216  stage: test
    30574217  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    30624222    CFLAGS: "-DMRB_WORD_BOXING=1"
    30634223    LDFLAGS: ''
    3064   script: env; ./minirake --verbose all test
    3065 Test clang-3.9 64bit_utf8:
     4224  script: env; rake --verbose all test
     4225Test clang-3.9 64bit_word_utf8:
    30664226  stage: test
    30674227  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    30724232    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    30734233    LDFLAGS: ''
    3074   script: env; ./minirake --verbose all test
    3075 Test clang-3.9 64bit_nan:
    3076   stage: test
    3077   image: registry.gitlab.com/dabroz/mruby:clang39_0.7
    3078   variables:
    3079     CC: clang-3.9
    3080     CXX: clang++-3.9
    3081     LD: clang-3.9
    3082     CFLAGS: "-DMRB_NAN_BOXING=1"
    3083     LDFLAGS: ''
    3084   script: env; ./minirake --verbose all test
    3085 Test clang-3.9 64bit_nan_utf8:
    3086   stage: test
    3087   image: registry.gitlab.com/dabroz/mruby:clang39_0.7
    3088   variables:
    3089     CC: clang-3.9
    3090     CXX: clang++-3.9
    3091     LD: clang-3.9
    3092     CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    3093     LDFLAGS: ''
    3094   script: env; ./minirake --verbose all test
     4234  script: env; rake --verbose all test
    30954235Test clang-3.9 64bit_int16:
    30964236  stage: test
     
    31024242    CFLAGS: "-DMRB_INT16=1"
    31034243    LDFLAGS: ''
    3104   script: env; ./minirake --verbose all test
     4244  script: env; rake --verbose all test
    31054245Test clang-3.9 64bit_int16_utf8:
    31064246  stage: test
     
    31124252    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    31134253    LDFLAGS: ''
    3114   script: env; ./minirake --verbose all test
     4254  script: env; rake --verbose all test
    31154255Test clang-3.9 64bit_int16_nan:
    31164256  stage: test
     
    31224262    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
    31234263    LDFLAGS: ''
    3124   script: env; ./minirake --verbose all test
     4264  script: env; rake --verbose all test
    31254265Test clang-3.9 64bit_int16_nan_utf8:
    31264266  stage: test
     
    31324272    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
    31334273    LDFLAGS: ''
    3134   script: env; ./minirake --verbose all test
     4274  script: env; rake --verbose all test
    31354275Test clang-3.9 64bit_int64:
     4276  stage: test
     4277  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4278  variables:
     4279    CC: clang-3.9
     4280    CXX: clang++-3.9
     4281    LD: clang-3.9
     4282    CFLAGS: "-DMRB_INT64=1"
     4283    LDFLAGS: ''
     4284  script: env; rake --verbose all test
     4285Test clang-3.9 64bit_int64_utf8:
     4286  stage: test
     4287  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4288  variables:
     4289    CC: clang-3.9
     4290    CXX: clang++-3.9
     4291    LD: clang-3.9
     4292    CFLAGS: "-DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     4293    LDFLAGS: ''
     4294  script: env; rake --verbose all test
     4295Test clang-3.9 64bit_int64_word:
    31364296  stage: test
    31374297  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    31424302    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    31434303    LDFLAGS: ''
    3144   script: env; ./minirake --verbose all test
    3145 Test clang-3.9 64bit_int64_utf8:
     4304  script: env; rake --verbose all test
     4305Test clang-3.9 64bit_int64_word_utf8:
    31464306  stage: test
    31474307  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    31524312    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    31534313    LDFLAGS: ''
    3154   script: env; ./minirake --verbose all test
     4314  script: env; rake --verbose all test
    31554315Test clang-3.9 64bit_float:
     4316  stage: test
     4317  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4318  variables:
     4319    CC: clang-3.9
     4320    CXX: clang++-3.9
     4321    LD: clang-3.9
     4322    CFLAGS: "-DMRB_USE_FLOAT=1"
     4323    LDFLAGS: ''
     4324  script: env; rake --verbose all test
     4325Test clang-3.9 64bit_float_utf8:
     4326  stage: test
     4327  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4328  variables:
     4329    CC: clang-3.9
     4330    CXX: clang++-3.9
     4331    LD: clang-3.9
     4332    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_UTF8_STRING=1"
     4333    LDFLAGS: ''
     4334  script: env; rake --verbose all test
     4335Test clang-3.9 64bit_float_word:
    31564336  stage: test
    31574337  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    31624342    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
    31634343    LDFLAGS: ''
    3164   script: env; ./minirake --verbose all test
    3165 Test clang-3.9 64bit_float_utf8:
     4344  script: env; rake --verbose all test
     4345Test clang-3.9 64bit_float_word_utf8:
    31664346  stage: test
    31674347  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    31724352    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    31734353    LDFLAGS: ''
    3174   script: env; ./minirake --verbose all test
     4354  script: env; rake --verbose all test
    31754355Test clang-3.9 64bit_float_int16:
    31764356  stage: test
     
    31824362    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
    31834363    LDFLAGS: ''
    3184   script: env; ./minirake --verbose all test
     4364  script: env; rake --verbose all test
    31854365Test clang-3.9 64bit_float_int16_utf8:
    31864366  stage: test
     
    31924372    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
    31934373    LDFLAGS: ''
    3194   script: env; ./minirake --verbose all test
     4374  script: env; rake --verbose all test
    31954375Test clang-3.9 64bit_float_int64:
     4376  stage: test
     4377  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4378  variables:
     4379    CC: clang-3.9
     4380    CXX: clang++-3.9
     4381    LD: clang-3.9
     4382    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1"
     4383    LDFLAGS: ''
     4384  script: env; rake --verbose all test
     4385Test clang-3.9 64bit_float_int64_utf8:
     4386  stage: test
     4387  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     4388  variables:
     4389    CC: clang-3.9
     4390    CXX: clang++-3.9
     4391    LD: clang-3.9
     4392    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
     4393    LDFLAGS: ''
     4394  script: env; rake --verbose all test
     4395Test clang-3.9 64bit_float_int64_word:
    31964396  stage: test
    31974397  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    32024402    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
    32034403    LDFLAGS: ''
    3204   script: env; ./minirake --verbose all test
    3205 Test clang-3.9 64bit_float_int64_utf8:
     4404  script: env; rake --verbose all test
     4405Test clang-3.9 64bit_float_int64_word_utf8:
    32064406  stage: test
    32074407  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
     
    32124412    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
    32134413    LDFLAGS: ''
    3214   script: env; ./minirake --verbose all test
     4414  script: env; rake --verbose all test
  • EcnlProtoTool/trunk/mruby-2.1.1/.project

    r331 r439  
    11<?xml version="1.0" encoding="UTF-8"?>
    22<projectDescription>
    3         <name>mruby-1.3.0</name>
     3        <name>mruby-2.1.1</name>
    44        <comment></comment>
    55        <projects>
  • EcnlProtoTool/trunk/mruby-2.1.1/.travis.yml

    r331 r439  
    66  include:
    77    - os: linux
    8       sudo: 9000
     8      sudo: false
    99    - os: osx
    1010      osx_image: xcode7.1
    1111
    12 addons:
    13   apt:
    14     packages:
    15       - gperf
    16 
    17 env: MRUBY_CONFIG=travis_config.rb
    18 script: "./minirake all test"
     12env:
     13  - MRUBY_CONFIG=travis_config.rb
     14script: "rake -m && rake test"
  • EcnlProtoTool/trunk/mruby-2.1.1/.yardopts

    r270 r439  
    1313-
    1414AUTHORS
    15 MITL
     15LICENSE
    1616CONTRIBUTING.md
    1717doc/guides/*.md
  • EcnlProtoTool/trunk/mruby-2.1.1/AUTHORS

    r331 r439  
    1 Original Authors "mruby developers" are:
    2    Yukihiro Matsumoto
     1This is the (likely incomplete) list of "mruby developers".
     2If you submit a patch to mruby, please add your name to the end
     3of this list.
     4
     5   Yukihiro Matsumoto (Matz)
    36   SCSK KYUSHU CORPORATION
    47   Kyushu Institute of Technology
     
    3740   Tomasz DÄ
    3841browski
     42   Christopher Aue
     43   Masahiro Wakame
     44   YAMAMOTO Masaya
     45   KOBAYASHI Shuji
     46   RIZAL Reckordp
  • EcnlProtoTool/trunk/mruby-2.1.1/CONTRIBUTING.md

    r270 r439  
    1010* Work on the latest possible state of **mruby/master**
    1111* Create a branch which is dedicated to your change
    12 * Test your changes before creating a pull request (```./minirake test```)
     12* Test your changes before creating a pull request (```rake test```)
    1313* If possible write a test case which confirms your change
    1414* Don't mix several features or bug-fixes in one pull request
     
    3434(http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf).
    3535
    36 Although we target C99, Visual C++ is also an important target for mruby. For
    37 this reason a declaration of a local variable has to be at the beginning of a
    38 scope block.
     36Although we target C99, we've heard some compilers in the embedded environment
     37still requires declarations of local variables to be at the beginning of a
     38scope. Until we confirm the situation has changed, we use the old-style
     39variable declaration.
     40
     41Visual C++ is also an important target for mruby (supported version is 2013 or
     42later). For this reason features that are not supported by Visual C++ may not
     43be used (e.g. `%z` of `strftime()`).
     44
     45NOTE: Old GCC requires `-std=gnu99` option to enable C99 support.
    3946
    4047#### Reduce library dependencies to a minimum
  • EcnlProtoTool/trunk/mruby-2.1.1/LEGAL

    r270 r439  
    33
    44All the files in this distribution are covered under the MIT license
    5 (see the file MITL) except some files mentioned below:
     5(see the file LICENSE) except some files mentioned below:
    66
  • EcnlProtoTool/trunk/mruby-2.1.1/Makefile

    r298 r439  
    11# mruby is using Rake (http://rake.rubyforge.org) as a build tool.
    2 # We provide a minimalistic version called minirake inside of our
    3 # codebase.
    42
    53RAKE = build.bat
  • EcnlProtoTool/trunk/mruby-2.1.1/README.md

    r331 r439  
    44
    55mruby is the lightweight implementation of the Ruby language complying to (part
    6 of) the [ISO standard][ISO-standard]. Its syntax is Ruby 1.9 compatible.
     6of) the [ISO standard][ISO-standard]. Its syntax is Ruby 2.x compatible.
    77
    88mruby can be linked and embedded within your application.  We provide the
     
    1818## How to get mruby
    1919
    20 The stable version 1.3.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/1.3.0.zip](https://github.com/mruby/mruby/archive/1.3.0.zip)
     20The stable version 2.1.1 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.1.1.zip](https://github.com/mruby/mruby/archive/2.1.1.zip)
    2121
    2222The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master)
     
    3131## mruby home-page
    3232
    33 The URL of the mruby home-page is: [http://www.mruby.org](http://www.mruby.org).
     33The URL of the mruby home-page is: https://mruby.org.
    3434
    3535## Mailing list
    3636
    37 We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby).
     37We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby/issues).
    3838
    3939## How to compile and install (mruby and gems)
    4040
    41 See the [doc/guides/compile.md](doc/guides/compile.md) file.
     41See the [compile.md](https://github.com/mruby/mruby/blob/master/doc/guides/compile.md) file.
    4242
    4343## Running Tests
     
    4545To run the tests, execute the following from the project's root directory.
    4646
    47     $ make test
     47    $ rake test
    4848
    49 Or
     49## Building documentation
    5050
    51     $ ruby ./minirake test
     51There are two sets of documentation in mruby: the mruby API (generated by yard) and C API (Doxygen)
     52
     53To build both of them, simply go
     54
     55    rake doc
     56
     57You can also view them in your browser
     58
     59    rake view_api
     60    rake view_capi
    5261
    5362## How to customize mruby (mrbgems)
     
    5564mruby contains a package manager called *mrbgems*. To create extensions
    5665in C and/or Ruby you should create a *GEM*. For a documentation of how to
    57 use mrbgems consult the file [doc/guides/mrbgems.md](doc/guides/mrbgems.md). For example code of
    58 how to use mrbgems look into the folder *examples/mrbgems/*.
     66use mrbgems consult the file [mrbgems.md](https://github.com/mruby/mruby/blob/master/doc/guides/mrbgems.md).
     67For example code of how to use mrbgems look into the folder *examples/mrbgems/*.
    5968
    6069## License
    6170
    62 mruby is released under the [MIT License](MITL).
     71mruby is released under the [MIT License](https://github.com/mruby/mruby/blob/master/LICENSE).
    6372
    6473## Note for License
     
    8998[ISO-standard]: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579
    9099[build-status-img]: https://travis-ci.org/mruby/mruby.svg?branch=master
    91 [contribution-guidelines]: CONTRIBUTING.md
     100[contribution-guidelines]: https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md
    92101[travis-ci]: https://travis-ci.org/mruby/mruby
  • EcnlProtoTool/trunk/mruby-2.1.1/Rakefile

    r331 r439  
    66MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd')
    77
     8Rake.verbose(false) if Rake.verbose == Rake::DSL::DEFAULT
     9
     10$LOAD_PATH << File.join(MRUBY_ROOT, "lib")
     11
    812# load build systems
    9 load "#{MRUBY_ROOT}/tasks/ruby_ext.rake"
    10 load "#{MRUBY_ROOT}/tasks/mruby_build.rake"
    11 load "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"
     13require "mruby-core-ext"
     14require "mruby/build"
    1215
    1316# load configuration file
     
    3033
    3134load "#{MRUBY_ROOT}/tasks/gitlab.rake"
     35load "#{MRUBY_ROOT}/tasks/doc.rake"
     36
     37def install_D(src, dst)
     38  rm_f dst
     39  mkdir_p File.dirname(dst)
     40  cp src, dst
     41end
    3242
    3343##############################
     
    3646
    3747bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin"
    38 FileUtils.mkdir_p bin_path, { :verbose => $verbose }
    3948
    4049depfiles = MRuby.targets['host'].bins.map do |bin|
     
    4352
    4453  file install_path => source_path do |t|
    45     FileUtils.rm_f t.name, { :verbose => $verbose }
    46     FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose }
     54    install_D t.prerequisites.first, t.name
    4755  end
    4856
     
    5664    current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}"
    5765
    58     if current_build_dir !~ /^#{build_dir}/
     66    if current_build_dir !~ /^#{Regexp.escape(build_dir)}/
    5967      current_build_dir = "#{build_dir}/mrbgems/#{gem.name}"
    6068    end
     
    6472      objs = Dir.glob("#{current_dir}/tools/#{bin}/*.{c,cpp,cxx,cc}").map { |f| objfile(f.pathmap("#{current_build_dir}/tools/#{bin}/%n")) }
    6573
    66       file exec => objs + [libfile("#{build_dir}/lib/libmruby")] do |t|
     74      file exec => objs + target.libraries do |t|
    6775        gem_flags = gems.map { |g| g.linker.flags }
    6876        gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries }
     
    7179        gem_library_paths = gems.map { |g| g.linker.library_paths }
    7280        linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries, gem_flags_after_libraries
     81
     82        gem.call_post_build_event target
    7383      end
    7484
     
    7787
    7888        file install_path => exec do |t|
    79           FileUtils.rm_f t.name, { :verbose => $verbose }
    80           FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose }
     89          install_D t.prerequisites.first, t.name
    8190        end
    8291        depfiles += [ install_path ]
     
    8695
    8796          file install_path => exec do |t|
    88             FileUtils.rm_f t.name, { :verbose => $verbose }
    89             FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose }
     97            install_D t.prerequisites.first, t.name
    9098          end
    9199          depfiles += [ install_path ]
     
    99107
    100108depfiles += MRuby.targets.map { |n, t|
    101   [t.libfile("#{t.build_dir}/lib/libmruby")]
     109  t.libraries
    102110}.flatten
    103111
     
    114122    print_build_summary
    115123  end
     124  MRuby::Lockfile.write
    116125end
    117126
    118127desc "run all mruby tests"
    119 task :test => ["all"] do
    120   MRuby.each_target do
    121     run_test if test_enabled?
     128task :test
     129MRuby.each_target do
     130  if test_enabled?
     131    t = :"test_#{self.name}"
     132    task t => ["all"] do
     133      run_test
     134    end
     135    task :test => t
     136  end
     137
     138  if bintest_enabled?
     139    t = :"bintest_#{self.name}"
     140    task t => ["all"] do
     141      run_bintest
     142    end
     143    task :test => t
    122144  end
    123145end
     
    126148task :clean do
    127149  MRuby.each_target do |t|
    128     FileUtils.rm_rf t.build_dir, { :verbose => $verbose }
     150    rm_rf t.build_dir
    129151  end
    130   FileUtils.rm_f depfiles, { :verbose => $verbose }
     152  rm_f depfiles
    131153  puts "Cleaned up target build folder"
    132154end
    133155
    134156desc "clean everything!"
    135 task :deep_clean => ["clean"] do
     157task :deep_clean => ["clean", "clean_doc"] do
    136158  MRuby.each_target do |t|
    137     FileUtils.rm_rf t.gem_clone_dir, { :verbose => $verbose }
     159    rm_rf t.gem_clone_dir
    138160  end
    139161  puts "Cleaned up mrbgems build folder"
    140162end
    141 
    142 desc 'generate document'
    143 task :doc do
    144   begin
    145     sh "mrbdoc"
    146   rescue
    147     puts "ERROR: To generate documents, you should install yard-mruby gem."
    148     puts "  $ gem install yard-mruby"
    149   end
    150 end
  • EcnlProtoTool/trunk/mruby-2.1.1/TODO

    r270 r439  
    33* special variables ($1,$2..)
    44* super in aliased methods
    5 * multi-assignment decomposing
    6 * keyword arguments in def statement
    75
    86Things to improve (Done but things to fix)
  • EcnlProtoTool/trunk/mruby-2.1.1/appveyor.yml

    r331 r439  
    11version: "{build}"
    22
    3 os: Visual Studio 2015
     3os: Visual Studio 2017
    44
    5 clone_depth: 50
     5shallow_clone: true
     6
     7
     8cache:
     9  - win_flex_bison
    610
    711
    812environment:
    913  matrix:
     14    # Visual Studio 2017 64bit
     15    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
     16
     17    # Visual Studio 2017 32bit
     18    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
     19      machine: x86
     20
    1021    # Visual Studio 2015 64bit
    1122    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
    1223      machine: amd64
     24
     25    # Visual Studio 2015 32bit
     26    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
     27      machine: x86
    1328
    1429    # Visual Studio 2013 64bit
     
    1934init:
    2035  - call "%visualcpp%" %machine%
    21   # For using bison.exe
    22   - set PATH=%PATH%;C:\cygwin\bin;
     36  # For using Rubyinstaller's Ruby 2.4 64bit
     37  - set PATH=C:\Ruby24-x64\bin;%PATH%
     38  - ruby --version
    2339
    2440
     41install:
     42  - if not exist win_flex_bison (
     43      appveyor DownloadFile "https://github.com/lexxmark/winflexbison/releases/download/v.2.5.10/win_flex_bison-2.5.10.zip" &
     44      7z x -y -owin_flex_bison win_flex_bison-2.5.10.zip
     45    )
     46
    2547build_script:
     48  - set YACC=.\win_flex_bison\win_bison.exe
    2649  - set MRUBY_CONFIG=appveyor_config.rb
    27   - ruby .\minirake test
     50  - rake -E $stdout.sync=true test
  • EcnlProtoTool/trunk/mruby-2.1.1/appveyor_config.rb

    r331 r439  
    1 MRuby::Build.new('debug') do |conf|
    2   toolchain :visualcpp
    3   enable_debug
    4 
    5   # include all core GEMs
    6   conf.gembox 'full-core'
    7   conf.compilers.each do |c|
    8     c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA)
    9   end
    10 
    11   build_mrbc_exec
    12 end
    13 
    141MRuby::Build.new('full-debug') do |conf|
    152  toolchain :visualcpp
     
    185  # include all core GEMs
    196  conf.gembox 'full-core'
    20   conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
     7  conf.cc.defines += %w(MRB_GC_STRESS MRB_METHOD_CACHE MRB_ENABLE_DEBUG_HOOK)
    218
    229  conf.enable_test
  • EcnlProtoTool/trunk/mruby-2.1.1/benchmark/bm_ao_render.rb

    r321 r439  
    6969    len = vlength
    7070    v = Vec.new(@x, @y, @z)
    71     if len > 1.0e-17 then
     71    if len > 1.0e-17
    7272      v.x = v.x / len
    7373      v.y = v.y / len
     
    9393    c = rs.vdot(rs) - (@radius * @radius)
    9494    d = b * b - c
    95     if d > 0.0 then
     95    if d > 0.0
    9696      t = - b - Math.sqrt(d)
    9797
    98       if t > 0.0 and t < isect.t then
     98      if t > 0.0 and t < isect.t
    9999        isect.t = t
    100100        isect.hit = true
     
    119119    v = ray.dir.vdot(@n)
    120120    v0 = v
    121     if v < 0.0 then
     121    if v < 0.0
    122122      v0 = -v
    123123    end
    124     if v0 < 1.0e-17 then
     124    if v0 < 1.0e-17
    125125      return
    126126    end
     
    128128    t = -(ray.org.vdot(@n) + d) / v
    129129
    130     if t > 0.0 and t < isect.t then
     130    if t > 0.0 and t < isect.t
    131131      isect.hit = true
    132132      isect.t = t
     
    171171def clamp(f)
    172172  i = f * 255.5
    173   if i > 255.0 then
     173  if i > 255.0
    174174    i = 255.0
    175175  end
    176   if i < 0.0 then
     176  if i < 0.0
    177177    i = 0.0
    178178  end
     
    184184  basis[1] = Vec.new(0.0, 0.0, 0.0)
    185185
    186   if n.x < 0.6 and n.x > -0.6 then
     186  if n.x < 0.6 and n.x > -0.6
    187187    basis[1].x = 1.0
    188   elsif n.y < 0.6 and n.y > -0.6 then
     188  elsif n.y < 0.6 and n.y > -0.6
    189189    basis[1].y = 1.0
    190   elsif n.z < 0.6 and n.z > -0.6 then
     190  elsif n.z < 0.6 and n.z > -0.6
    191191    basis[1].z = 1.0
    192192  else
     
    222222                isect.pl.y + eps * isect.n.y,
    223223                isect.pl.z + eps * isect.n.z)
    224     nphi.times do |j|
    225       ntheta.times do |i|
     224    nphi.times do
     225      ntheta.times do
    226226        r = Rand::rand
    227227        phi = 2.0 * 3.14159265 * Rand::rand
     
    242242        @spheres[2].intersect(ray, occisect)
    243243        @plane.intersect(ray, occisect)
    244         if occisect.hit then
     244        if occisect.hit
    245245          occlusion = occlusion + 1.0
    246246        else
     
    284284            @spheres[2].intersect(ray, isect)
    285285            @plane.intersect(ray, isect)
    286             if isect.hit then
     286            if isect.hit
    287287              col = ambient_occlusion(isect)
    288288              rad.x = rad.x + col.x
  • EcnlProtoTool/trunk/mruby-2.1.1/benchmark/bm_app_lc_fizzbuzz.rb

    r321 r439  
    4949end
    5050
    51 answer_str = answer.to_a
    52 # puts answer_str
     51# puts answer
  • EcnlProtoTool/trunk/mruby-2.1.1/benchmark/bm_so_lists.rb

    r321 r439  
    1818  # remove each individual item from right side of li3 and
    1919  # append to right side of li2 (reversing list)
    20   while (not li3.empty?)
     20  until li3.empty?
    2121    li2.push(li3.pop)
    2222  end
     
    2525  li1.reverse!
    2626  # check that first item is now SIZE
    27   if li1[0] != SIZE then
     27  if li1[0] != SIZE
    2828    p "not SIZE"
    2929    0
    3030  else
    3131    # compare li1 and li2 for equality
    32     if li1 != li2 then
     32    if li1 != li2
    3333      return(0)
    3434    else
  • EcnlProtoTool/trunk/mruby-2.1.1/build.bat

    r424 r439  
    77cd /d %DIR%
    88
    9 ruby -Eutf-8 ./minirake %1
     9rake %1
  • EcnlProtoTool/trunk/mruby-2.1.1/build_config.rb

    r424 r439  
    33
    44  # Gets set by the VS command prompts.
    5   #if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
     5  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
    66    toolchain :visualcpp
    7   #else
    8   #  toolchain :gcc
    9   #end
    10 
    11   enable_debug
     7  else
     8    toolchain :gcc
     9  end
     10
     11  # Turn on `enable_debug` for better debugging
     12  # enable_debug
    1213
    1314  # Use mrbgems
     
    1819  # conf.gem 'examples/mrbgems/c_and_ruby_extension_example'
    1920  # conf.gem :core => 'mruby-eval'
    20   # conf.gem :mgem => 'mruby-io'
    21   # conf.gem :github => 'iij/mruby-io'
    22   # conf.gem :git => 'git@github.com:iij/mruby-io.git', :branch => 'master', :options => '-v'
     21  # conf.gem :mgem => 'mruby-onig-regexp'
     22  # conf.gem :github => 'mattn/mruby-onig-regexp'
     23  # conf.gem :git => 'git@github.com:mattn/mruby-onig-regexp.git', :branch => 'master', :options => '-v'
    2324
    2425  # include the default GEMs
     
    2930  #   cc.flags = [ENV['CFLAGS'] || %w()]
    3031  #   cc.include_paths = ["#{root}/include"]
    31   #   cc.defines = %w(DISABLE_GEMS)
    32   #   cc.option_include_path = '-I%s'
     32  #   cc.defines = %w()
     33  #   cc.option_include_path = %q[-I"%s"]
    3334  #   cc.option_define = '-D%s'
    34   #   cc.compile_options = "%{flags} -MMD -o %{outfile} -c %{infile}"
     35  #   cc.compile_options = %Q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
    3536  # end
    3637
     
    5051  #   linker.option_library = '-l%s'
    5152  #   linker.option_library_path = '-L%s'
    52   #   linker.link_options = "%{flags} -o %{outfile} %{objs} %{libs}"
     53  #   linker.link_options = "%{flags} -o "%{outfile}" %{objs} %{libs}"
    5354  # end
    5455
     
    5657  # conf.archiver do |archiver|
    5758  #   archiver.command = ENV['AR'] || 'ar'
    58   #   archiver.archive_options = 'rs %{outfile} %{objs}'
     59  #   archiver.archive_options = 'rs "%{outfile}" %{objs}'
    5960  # end
    6061
     
    6263  # conf.yacc do |yacc|
    6364  #   yacc.command = ENV['YACC'] || 'bison'
    64   #   yacc.compile_options = '-o %{outfile} %{infile}'
     65  #   yacc.compile_options = %q[-o "%{outfile}" "%{infile}"]
    6566  # end
    6667
     
    6869  # conf.gperf do |gperf|
    6970  #   gperf.command = 'gperf'
    70   #   gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
     71  #   gperf.compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
    7172  # end
    7273
     
    8485  # conf.enable_bintest
    8586end
    86 
     87=begin
    8788MRuby::Build.new('host-debug') do |conf|
    8889  # load specific toolchain settings
     
    110111end
    111112
    112 #MRuby::Build.new('test') do |conf|
     113MRuby::Build.new('test') do |conf|
     114  # Gets set by the VS command prompts.
     115  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
     116    toolchain :visualcpp
     117  else
     118    toolchain :gcc
     119  end
     120
     121  enable_debug
     122  conf.enable_bintest
     123  conf.enable_test
     124
     125  conf.gembox 'default'
     126end
     127=end
     128#MRuby::Build.new('bench') do |conf|
    113129#  # Gets set by the VS command prompts.
    114130#  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
     
    116132#  else
    117133#    toolchain :gcc
     134#    conf.cc.flags << '-O3'
    118135#  end
    119 #
    120 #  enable_debug
    121 #  conf.enable_bintest
    122 #  conf.enable_test
    123136#
    124137#  conf.gembox 'default'
     
    137150#
    138151#   conf.test_runner.command = 'env'
    139 #
    140152# end
    141153
    142 # Define cross build settings
     154# Cross build for arm-none-eabi
    143155MRuby::CrossBuild.new('arm-none-eabi') do |conf|
    144156  toolchain :gcc
     
    149161  conf.archiver.command = "arm-none-eabi-ar"
    150162
    151   conf.cc.flags << %w(-MD -MP -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -nostdinc)
     163  conf.cc.flags << %w(-MD -MP -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -nostdinc -Wstack-usage=256 -ffunction-sections -fdata-sections)
    152164  conf.cc.include_paths  << "../musl-1.1.18/include"
    153165
    154   conf.linker.flags << %w(-nostdlib)
    155   conf.linker.library_paths << "../musl-1.1.18/lib"
    156   conf.linker.libraries << %w(c gcc)
    157 
    158   #configuration for low memory environment
    159   conf.cc.defines << %w(MRB_GC_STRESS)
    160   #conf.cc.defines << %w(DISABLE_STDIO)
    161   conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
    162 
    163   conf.build_mrbtest_lib_only
     166  conf.cc.defines << %w(MRB_USE_CUSTOM_RO_DATA_P MRB_ENABLE_DEBUG_HOOK MRB_CONSTRAINED_BASELINE_PROFILE)
     167
     168  #conf.build_mrbtest_lib_only
    164169
    165170  conf.gem "#{root}/mrbgems/mruby-compiler"
     171  conf.gem "#{root}/mrbgems/mruby-eval"
     172  conf.gem "#{root}/mrbgems/mruby-io"
     173  conf.gem "#{root}/mrbgems/mruby-math"
     174  conf.gem "#{root}/mrbgems/mruby-pack"
     175  conf.gem "#{root}/mrbgems/mruby-print"
     176  conf.gem "#{root}/mrbgems/mruby-random"
     177  conf.gem "#{root}/mrbgems/mruby-socket"
     178  conf.gem "#{root}/mrbgems/mruby-sprintf"
     179  conf.gem "#{root}/mrbgems/mruby-struct"
     180  conf.gem "#{root}/mrbgems/mruby-time"
    166181  conf.gem "#{root}/mrbgems/mruby-numeric-ext"
    167182  conf.gem "#{root}/mrbgems/mruby-string-ext"
    168183  conf.gem '../mrbgems/mruby-onig-regexp'  do |g|
     184    g.cc.flags << %w(-DHAVE_ONIGMO_H)
    169185    g.cc.include_paths  << "../onigmo-6.1.3/src"
    170186  end
     
    177193  conf.gem "#{root}/../mrbgems/mruby-errno"
    178194  conf.gem "#{root}/../mrbgems/mruby-iijson"
    179   conf.gem "#{root}/../mrbgems/mruby-io"
    180195  conf.gem "#{root}/../mrbgems/mruby-ipaddr"
    181196  conf.gem "#{root}/../mrbgems/mruby-mock"
    182   conf.gem "#{root}/../mrbgems/mruby-pack"
    183197  #conf.gem "#{root}/../mrbgems/mruby-require"
    184   conf.gem "#{root}/../mrbgems/mruby-socket"
    185198  conf.gem "#{root}/../mrbgems/mruby-tls-openssl" do |g|
    186199    g.cc.include_paths << "#{g.dir}/../../openssl-1.1.0e/include"
     
    202215
    203216  conf.archiver.command = "llvm-ar"
     217  conf.cc.flags << '-ffunction-sections -fdata-sections'
     218  conf.linker.flags << '-Wl,--gc-sections'
    204219  conf.linker.flags << '--save-bc %{outfile}.bc --pre-js ../webapp/webmrbc/pre.js --post-js ../webapp/webmrbc/post.js --use-preload-plugins'
    205220  #conf.linker.flags << '-s BINARYEN=1'
     
    207222
    208223  # include the default GEMs
    209   conf.gembox 'default'
     224  #conf.gembox 'default'
    210225  conf.gem :core => 'mruby-bin-mrbc'
    211226end
  • EcnlProtoTool/trunk/mruby-2.1.1/examples/targets/build_config_ArduinoDue.rb

    r321 r439  
    4343                -Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=156 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM
    4444                -D__SAM3X8E__ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due")
    45     cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
     45    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
    4646
    4747    #configuration for low memory environment
    4848    cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
    49     cc.defines << %w(MRB_USE_IV_SEGLIST)
    5049    cc.defines << %w(KHASH_DEFAULT_SIZE=8)
    5150    cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
     
    6665  conf.archiver do |archiver|
    6766    archiver.command = "#{BIN_PATH}/arm-none-eabi-ar"
    68     archiver.archive_options = 'rcs %{outfile} %{objs}'
     67    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
    6968  end
    7069
  • EcnlProtoTool/trunk/mruby-2.1.1/examples/targets/build_config_IntelEdison.rb

    r331 r439  
    3333    cc.flags << %w(-O2 -pipe -g -feliminate-unused-debug-types)
    3434    cc.flags << "--sysroot=#{POKY_EDISON_SYSROOT}"
    35     cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
     35    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
    3636    cc.defines = %w(ENABLE_READLINE)
    3737  end
     
    4848  conf.archiver do |archiver|
    4949    archiver.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-ar"
    50     archiver.archive_options = 'rcs %{outfile} %{objs}'
     50    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
    5151  end
    5252
  • EcnlProtoTool/trunk/mruby-2.1.1/examples/targets/build_config_IntelGalileo.rb

    r321 r439  
    4040              -ffunction-sections -fdata-sections -MMD -DARDUINO=153)
    4141    cc.flags << "--sysroot=#{GALILEO_SYSROOT}"
    42     cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
     42    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
    4343  end
    4444
     
    5555  conf.archiver do |archiver|
    5656    archiver.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-ar"
    57     archiver.archive_options = 'rcs %{outfile} %{objs}'
     57    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
    5858  end
    5959
  • EcnlProtoTool/trunk/mruby-2.1.1/examples/targets/build_config_RX630.rb

    r331 r439  
    2828    cc.command = "#{BIN_PATH}/rx-elf-gcc"
    2929    cc.flags = "-Wall -g -O2 -flto -mcpu=rx600 -m64bit-doubles"
    30     cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
     30    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
    3131
    3232    #configuration for low memory environment
    3333    cc.defines << %w(MRB_USE_FLOAT)
    3434    cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
    35     cc.defines << %w(MRB_USE_IV_SEGLIST)
    3635    cc.defines << %w(KHASH_DEFAULT_SIZE=8)
    3736    cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
     
    5554  conf.archiver do |archiver|
    5655    archiver.command = "#{BIN_PATH}/rx-elf-ar"
    57     archiver.archive_options = 'rcs %{outfile} %{objs}'
     56    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
    5857  end
    5958
  • EcnlProtoTool/trunk/mruby-2.1.1/examples/targets/build_config_android_arm64-v8a.rb

    r331 r439  
    1616# Requires Android NDK r13 or later.
    1717MRuby::CrossBuild.new('android-arm64-v8a') do |conf|
    18   params = { 
    19     :arch => 'arm64-v8a', 
     18  params = {
     19    :arch => 'arm64-v8a',
    2020    :platform => 'android-24',
    2121    :toolchain => :clang,
  • EcnlProtoTool/trunk/mruby-2.1.1/examples/targets/build_config_android_armeabi.rb

    r331 r439  
    1616# Requires Android NDK r13 or later.
    1717MRuby::CrossBuild.new('android-armeabi') do |conf|
    18   params = { 
    19     :arch => 'armeabi', 
     18  params = {
     19    :arch => 'armeabi',
    2020    :platform => 'android-24',
    2121    :toolchain => :clang,
  • EcnlProtoTool/trunk/mruby-2.1.1/examples/targets/build_config_chipKITMax32.rb

    r321 r439  
    4040                -fno-short-double -mprocessor=32MX795F512L -DF_CPU=80000000L -DARDUINO=23 -D_BOARD_MEGA_
    4141                -DMPIDEVER=0x01000202 -DMPIDE=23)
    42     cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
     42    cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
    4343
    4444    #configuration for low memory environment
    4545    cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
    46     cc.defines << %w(MRB_USE_IV_SEGLIST)
    4746    cc.defines << %w(KHASH_DEFAULT_SIZE=8)
    4847    cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
     
    6261  conf.archiver do |archiver|
    6362    archiver.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-ar"
    64     archiver.archive_options = 'rcs %{outfile} %{objs}'
     63    archiver.archive_options = 'rcs "%{outfile}" %{objs}'
    6564  end
    6665
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mrbconf.h

    r331 r439  
    2929//#define MRB_USE_FLOAT
    3030
    31 /* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT64 */
    32 //#define MRB_INT16
    33 
    34 /* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT16 */
     31/* exclude floating point numbers */
     32//#define MRB_WITHOUT_FLOAT
     33
     34/* add -DMRB_METHOD_CACHE to use method cache to improve performance */
     35//#define MRB_METHOD_CACHE
     36/* size of the method cache (need to be the power of 2) */
     37//#define MRB_METHOD_CACHE_SIZE (1<<7)
     38
     39/* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */
     40/* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
     41#ifndef MRB_METHOD_T_STRUCT
     42  // can't use highest 2 bits of function pointers on 32bit Windows.
     43# if defined(_WIN32) && !defined(_WIN64)
     44#   define MRB_METHOD_T_STRUCT
     45# endif
     46#endif
     47
     48/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64;
     49   Default for 32-bit CPU mode. */
     50//#define MRB_INT32
     51
     52/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT32;
     53   Default for 64-bit CPU mode. */
    3554//#define MRB_INT64
    3655
    37 /* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT */
     56/* if no specific integer type is chosen */
     57#if !defined(MRB_INT32) && !defined(MRB_INT64)
     58# if defined(MRB_64BIT) && !defined(MRB_NAN_BOXING)
     59/* Use 64bit integers on 64bit architecture (without MRB_NAN_BOXING) */
     60#  define MRB_INT64
     61# else
     62/* Otherwise use 32bit integers */
     63#  define MRB_INT32
     64# endif
     65#endif
     66
     67/* define on big endian machines; used by MRB_NAN_BOXING, etc. */
     68#ifndef MRB_ENDIAN_BIG
     69# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
     70     (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
     71#  define MRB_ENDIAN_BIG
     72# endif
     73#endif
     74
     75/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT and MRB_WITHOUT_FLOAT */
    3876//#define MRB_NAN_BOXING
    39 
    40 /* define on big endian machines; used by MRB_NAN_BOXING */
    41 //#define MRB_ENDIAN_BIG
    4277
    4378/* represent mrb_value as a word (natural unit of data for the processor) */
     
    5388//#define MRB_HEAP_PAGE_SIZE 1024
    5489
    55 /* use segmented list for IV table */
    56 //#define MRB_USE_IV_SEGLIST
    57 
    58 /* initial size for IV khash; ignored when MRB_USE_IV_SEGLIST is set */
    59 //#define MRB_IVHASH_INIT_SIZE 8
    60 
    61 /* if _etext and _edata available, mruby can reduce memory used by symbols */
    62 //#define MRB_USE_ETEXT_EDATA
    63 
    64 /* do not use __init_array_start to determine readonly data section;
    65    effective only when MRB_USE_ETEXT_EDATA is defined */
    66 //#define MRB_NO_INIT_ARRAY_START
     90/* if __ehdr_start is available, mruby can reduce memory used by symbols */
     91//#define MRB_USE_LINK_TIME_RO_DATA_P
     92
     93/* if MRB_USE_LINK_TIME_RO_DATA_P does not work,
     94   you can try mrb_ro_data_p() that you have implemented yourself in any file;
     95   prototype is `mrb_bool mrb_ro_data_p(const char *ptr)` */
     96//#define MRB_USE_CUSTOM_RO_DATA_P
    6797
    6898/* turn off generational GC by default */
     
    94124
    95125/* -DMRB_DISABLE_XXXX to drop following features */
    96 //#define MRB_DISABLE_STDIO     /* use of stdio */
     126//#define MRB_DISABLE_STDIO /* use of stdio */
    97127
    98128/* -DMRB_ENABLE_XXXX to enable following features */
    99 //#define MRB_ENABLE_DEBUG_HOOK /* hooks for debugger */
     129//#define MRB_ENABLE_DEBUG_HOOK /* hooks for debugger */
     130//#define MRB_ENABLE_ALL_SYMBOLS /* Symbols.all_symbols */
    100131
    101132/* end of configuration */
     
    123154#endif
    124155
     156/*
     157** mruby tuning profiles
     158**/
     159
     160/* A profile for micro controllers */
     161#if defined(MRB_CONSTRAINED_BASELINE_PROFILE)
     162# ifndef KHASH_DEFAULT_SIZE
     163#  define KHASH_DEFAULT_SIZE 16
     164# endif
     165
     166# ifndef MRB_STR_BUF_MIN_SIZE
     167#  define MRB_STR_BUF_MIN_SIZE 32
     168# endif
     169
     170# ifndef MRB_HEAP_PAGE_SIZE
     171#  define MRB_HEAP_PAGE_SIZE 256
     172# endif
     173
     174/* A profile for default mruby */
     175#elif defined(MRB_BASELINE_PROFILE)
     176
     177/* A profile for desktop computers or workstations; rich memory! */
     178#elif defined(MRB_MAIN_PROFILE)
     179# ifndef MRB_METHOD_CACHE
     180#  define MRB_METHOD_CACHE
     181# endif
     182
     183# ifndef MRB_METHOD_CACHE_SIZE
     184#  define MRB_METHOD_CACHE_SIZE (1<<10)
     185# endif
     186
     187# ifndef MRB_IV_SEGMENT_SIZE
     188#  define MRB_IV_SEGMENT_SIZE 32
     189# endif
     190
     191# ifndef MRB_HEAP_PAGE_SIZE
     192#  define MRB_HEAP_PAGE_SIZE 4096
     193# endif
     194
     195/* A profile for server; mruby vm is long life */
     196#elif defined(MRB_HIGH_PROFILE)
     197# ifndef MRB_METHOD_CACHE
     198#  define MRB_METHOD_CACHE
     199# endif
     200
     201# ifndef MRB_METHOD_CACHE_SIZE
     202#  define MRB_METHOD_CACHE_SIZE (1<<12)
     203# endif
     204
     205# ifndef MRB_IV_SEGMENT_SIZE
     206#  define MRB_IV_SEGMENT_SIZE 64
     207# endif
     208
     209# ifndef MRB_HEAP_PAGE_SIZE
     210#  define MRB_HEAP_PAGE_SIZE 4096
     211# endif
     212#endif
     213
    125214#endif  /* MRUBYCONF_H */
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby.h

    r331 r439  
    22** mruby - An embeddable Ruby implementation
    33**
    4 ** Copyright (c) mruby developers 2010-2017
     4** Copyright (c) mruby developers 2010-2020
    55**
    66** Permission is hereby granted, free of charge, to any person obtaining
     
    2626*/
    2727
     28/**
     29 * @file mruby.h
     30 */
     31
    2832#ifndef MRUBY_H
    2933#define MRUBY_H
     
    3539#endif
    3640
     41#include <stdarg.h>
    3742#include <stdint.h>
    3843#include <stddef.h>
     
    5863#endif
    5964
    60 #if __STDC_VERSION__ >= 201112L
     65#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
    6166#define mrb_static_assert(exp, str) _Static_assert(exp, str)
    6267#else
     
    6570
    6671#include "mrbconf.h"
     72
     73#include <mruby/common.h>
     74#include <mruby/value.h>
     75#include <mruby/gc.h>
     76#include <mruby/version.h>
     77
     78#ifdef _MSC_VER
     79#include <float.h>
     80#endif
     81
     82#ifndef MRB_WITHOUT_FLOAT
     83#ifndef FLT_EPSILON
     84#define FLT_EPSILON (1.19209290e-07f)
     85#endif
     86#ifndef DBL_EPSILON
     87#define DBL_EPSILON ((double)2.22044604925031308085e-16L)
     88#endif
     89#ifndef LDBL_EPSILON
     90#define LDBL_EPSILON (1.08420217248550443401e-19L)
     91#endif
    6792
    6893#ifdef MRB_USE_FLOAT
     
    7196#define MRB_FLOAT_EPSILON DBL_EPSILON
    7297#endif
    73 
    74 #include "mruby/common.h"
    75 #include <mruby/value.h>
    76 #include <mruby/gc.h>
    77 #include <mruby/version.h>
     98#endif
    7899
    79100/**
     
    82103MRB_BEGIN_DECL
    83104
    84 typedef uint32_t mrb_code;
    85 
    86 /**
    87  * Required arguments signature type.
     105typedef uint8_t mrb_code;
     106
     107/**
     108 * \class mrb_aspec
     109 *
     110 * Specifies the number of arguments a function takes
     111 *
     112 * Example: `MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1)` for a method that expects 2..3 arguments
    88113 */
    89114typedef uint32_t mrb_aspec;
    90 
    91115
    92116struct mrb_irep;
     
    112136  struct RProc *proc;
    113137  mrb_value *stackent;
    114   int nregs;
    115   int ridx;
    116   int epos;
     138  uint16_t ridx;
     139  uint16_t epos;
    117140  struct REnv *env;
    118   mrb_code *pc;                 /* return address */
    119   mrb_code *err;                /* error position */
     141  const mrb_code *pc;           /* return address */
     142  const mrb_code *err;          /* error position */
    120143  int argc;
    121144  int acc;
     
    141164  mrb_callinfo *cibase, *ciend;
    142165
    143   mrb_code **rescue;                      /* exception handler stack */
    144   int rsize;
     166  uint16_t *rescue;                       /* exception handler stack */
     167  uint16_t rsize;
    145168  struct RProc **ensure;                  /* ensure handler stack */
    146   int esize, eidx;
     169  uint16_t esize, eidx;
    147170
    148171  enum mrb_fiber_state status;
     
    151174};
    152175
     176#ifdef MRB_METHOD_CACHE_SIZE
     177# define MRB_METHOD_CACHE
     178#else
     179/* default method cache size: 128 */
     180/* cache size needs to be power of 2 */
     181# define MRB_METHOD_CACHE_SIZE (1<<7)
     182#endif
     183
     184/**
     185 * Function pointer type for a function callable by mruby.
     186 *
     187 * The arguments to the function are stored on the mrb_state. To get them see mrb_get_args
     188 *
     189 * @param mrb The mruby state
     190 * @param self The self object
     191 * @return [mrb_value] The function's return value
     192 */
     193typedef mrb_value (*mrb_func_t)(struct mrb_state *mrb, mrb_value self);
     194
     195#ifndef MRB_METHOD_T_STRUCT
     196typedef uintptr_t mrb_method_t;
     197#else
     198typedef struct {
     199  uint8_t flags;
     200  union {
     201    struct RProc *proc;
     202    mrb_func_t func;
     203  };
     204} mrb_method_t;
     205#endif
     206
     207#ifdef MRB_METHOD_CACHE
     208struct mrb_cache_entry {
     209  struct RClass *c, *c0;
     210  mrb_sym mid;
     211  mrb_method_t m;
     212};
     213#endif
     214
    153215struct mrb_jmpbuf;
    154216
    155217typedef void (*mrb_atexit_func)(struct mrb_state*);
    156 
    157 #define MRB_STATE_NO_REGEXP 1
    158 #define MRB_STATE_REGEXP    2
    159218
    160219typedef struct mrb_state {
    161220  struct mrb_jmpbuf *jmp;
    162221
    163   uint32_t flags;
    164222  mrb_allocf allocf;                      /* memory allocation function */
    165223  void *allocf_ud;                        /* auxiliary data of allocf */
     
    179237  struct RClass *array_class;
    180238  struct RClass *hash_class;
    181 
     239  struct RClass *range_class;
     240
     241#ifndef MRB_WITHOUT_FLOAT
    182242  struct RClass *float_class;
     243#endif
    183244  struct RClass *fixnum_class;
    184245  struct RClass *true_class;
     
    188249  struct RClass *kernel_module;
    189250
    190   struct alloca_header *mems;
    191251  mrb_gc gc;
    192252
     253#ifdef MRB_METHOD_CACHE
     254  struct mrb_cache_entry cache[MRB_METHOD_CACHE_SIZE];
     255#endif
     256
    193257  mrb_sym symidx;
    194   struct kh_n2s *name2sym;      /* symbol hash */
    195258  struct symbol_name *symtbl;   /* symbol table */
     259  mrb_sym symhash[256];
    196260  size_t symcapa;
     261#ifndef MRB_ENABLE_SYMBOLL_ALL
     262  char symbuf[8];               /* buffer for small symbol names */
     263#endif
    197264
    198265#ifdef MRB_ENABLE_DEBUG_HOOK
    199   void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
    200   void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
     266  void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
     267  void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
    201268#endif
    202269
     
    220287  mrb_atexit_func *atexit_stack;
    221288#endif
    222   mrb_int atexit_stack_len;
     289  uint16_t atexit_stack_len;
     290  uint16_t ecall_nest;                    /* prevent infinite recursive ecall() */
    223291} mrb_state;
    224 
    225 
    226 typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
    227292
    228293/**
     
    241306 *      }
    242307 *
    243  * @param [mrb_state *] mrb The current mruby state.
    244  * @param [const char *] name The name of the defined class.
    245  * @param [struct RClass *] super The new class parent.
     308 * @param mrb The current mruby state.
     309 * @param name The name of the defined class.
     310 * @param super The new class parent.
    246311 * @return [struct RClass *] Reference to the newly defined class.
    247312 * @see mrb_define_class_under
     
    252317 * Defines a new module.
    253318 *
    254  * @param [mrb_state *] mrb_state* The current mruby state.
    255  * @param [const char *] char* The name of the module.
     319 * @param mrb The current mruby state.
     320 * @param name The name of the module.
    256321 * @return [struct RClass *] Reference to the newly defined module.
    257322 */
    258 MRB_API struct RClass *mrb_define_module(mrb_state *, const char*);
    259 MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value);
     323MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name);
     324MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val);
    260325
    261326/**
     
    266331 *     include A
    267332 *   end
    268  * @param [mrb_state *] mrb_state* The current mruby state.
    269  * @param [struct RClass *] RClass* A reference to module or a class.
    270  * @param [struct RClass *] RClass* A reference to the module to be included.
    271  */
    272 MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
     333 * @param mrb The current mruby state.
     334 * @param cla A reference to module or a class.
     335 * @param included A reference to the module to be included.
     336 */
     337MRB_API void mrb_include_module(mrb_state *mrb, struct RClass *cla, struct RClass *included);
    273338
    274339/**
     
    279344 *    prepend A
    280345 *  end
    281  * @param [mrb_state *] mrb_state* The current mruby state.
    282  * @param [struct RClass *] RClass* A reference to module or a class.
    283  * @param [struct RClass *] RClass* A reference to the module to be prepended.
    284  */
    285 MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
     346 * @param mrb The current mruby state.
     347 * @param cla A reference to module or a class.
     348 * @param prepended A reference to the module to be prepended.
     349 */
     350MRB_API void mrb_prepend_module(mrb_state *mrb, struct RClass *cla, struct RClass *prepended);
    286351
    287352/**
     
    292357 * Example:
    293358 *
    294  *     !!!c
    295359 *     mrb_value example_method(mrb_state* mrb, mrb_value self)
    296360 *     {
     
    304368 *     }
    305369 *
    306  * @param [mrb_state *] mrb The MRuby state reference.
    307  * @param [struct RClass *] cla The class pointer where the method will be defined.
    308  * @param [const char *] name The name of the method being defined.
    309  * @param [mrb_func_t] func The function pointer to the method definition.
    310  * @param [mrb_aspec] aspec The method parameters declaration.
     370 * @param mrb The MRuby state reference.
     371 * @param cla The class pointer where the method will be defined.
     372 * @param name The name of the method being defined.
     373 * @param func The function pointer to the method definition.
     374 * @param aspec The method parameters declaration.
    311375 */
    312376MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec);
     
    331395 *       mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
    332396 *     }
    333  * @param [mrb_state *] mrb_state* The MRuby state reference.
    334  * @param [struct RClass *] RClass* The class where the class method will be defined.
    335  * @param [const char *] char* The name of the class method being defined.
    336  * @param [mrb_func_t] mrb_func_t The function pointer to the class method definition.
    337  * @param [mrb_aspec] mrb_aspec The method parameters declaration.
    338  */
    339 MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec);
    340 MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec);
    341 
    342 /**
    343  *  Defines a module fuction.
     397 * @param mrb The MRuby state reference.
     398 * @param cla The class where the class method will be defined.
     399 * @param name The name of the class method being defined.
     400 * @param fun The function pointer to the class method definition.
     401 * @param aspec The method parameters declaration.
     402 */
     403MRB_API void mrb_define_class_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
     404
     405/**
     406 * Defines a singleton method
     407 *
     408 * @see mrb_define_class_method
     409 */
     410MRB_API void mrb_define_singleton_method(mrb_state *mrb, struct RObject *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
     411
     412/**
     413 *  Defines a module function.
    344414 *
    345415 * Example:
     
    359429 *          mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
    360430 *        }
    361  *  @param [mrb_state *] mrb_state* The MRuby state reference.
    362  *  @param [struct RClass *] RClass* The module where the module function will be defined.
    363  *  @param [const char *] char* The name of the module function being defined.
    364  *  @param [mrb_func_t] mrb_func_t The function pointer to the module function definition.
    365  *  @param [mrb_aspec] mrb_aspec The method parameters declaration.
    366  */
    367 MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
     431 *  @param mrb The MRuby state reference.
     432 *  @param cla The module where the module function will be defined.
     433 *  @param name The name of the module function being defined.
     434 *  @param fun The function pointer to the module function definition.
     435 *  @param aspec The method parameters declaration.
     436 */
     437MRB_API void mrb_define_module_function(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
    368438
    369439/**
     
    388458 *          mrb_example_gem_final(mrb_state* mrb){
    389459 *          }
    390  *  @param [mrb_state *] mrb_state* The MRuby state reference.
    391  *  @param [struct RClass *] RClass* A class or module the constant is defined in.
    392  *  @param [const char *] name The name of the constant being defined.
    393  *  @param [mrb_value] mrb_value The value for the constant.
    394  */
    395 MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
     460 *  @param mrb The MRuby state reference.
     461 *  @param cla A class or module the constant is defined in.
     462 *  @param name The name of the constant being defined.
     463 *  @param val The value for the constant.
     464 */
     465MRB_API void mrb_define_const(mrb_state* mrb, struct RClass* cla, const char *name, mrb_value val);
    396466
    397467/**
     
    439509 *     mrb_example_gem_final(mrb_state* mrb){
    440510 *     }
    441  * @param [mrb_state*] mrb_state* The mruby state reference.
    442  * @param [struct RClass*] RClass* A class the method will be undefined from.
    443  * @param [const char*] constchar* The name of the method to be undefined.
    444  */
    445 MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*);
     511 * @param mrb The mruby state reference.
     512 * @param cla The class the method will be undefined from.
     513 * @param name The name of the method to be undefined.
     514 */
     515MRB_API void mrb_undef_method(mrb_state *mrb, struct RClass *cla, const char *name);
     516MRB_API void mrb_undef_method_id(mrb_state*, struct RClass*, mrb_sym);
    446517
    447518/**
     
    478549 *      mrb_example_gem_final(mrb_state* mrb){
    479550 *      }
    480  * @param [mrb_state*] mrb_state* The mruby state reference.
    481  * @param [RClass*] RClass* A class the class method will be undefined from.
    482  * @param [constchar*] constchar* The name of the class method to be undefined.
    483  */
    484 MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
    485 
    486 /**
    487  * Initialize a new object instace of c class.
     551 * @param mrb The mruby state reference.
     552 * @param cls A class the class method will be undefined from.
     553 * @param name The name of the class method to be undefined.
     554 */
     555MRB_API void mrb_undef_class_method(mrb_state *mrb, struct RClass *cls, const char *name);
     556
     557/**
     558 * Initialize a new object instance of c class.
    488559 *
    489560 * Example:
     
    506577 *       mrb_p(mrb, obj); // => Kernel#p
    507578 *      }
    508  * @param [mrb_state*] mrb The current mruby state.
    509  * @param [RClass*] c Reference to the class of the new object.
    510  * @param [mrb_int] argc Number of arguments in argv
    511  * @param [const mrb_value *] argv Array of mrb_value to initialize the object
     579 * @param mrb The current mruby state.
     580 * @param c Reference to the class of the new object.
     581 * @param argc Number of arguments in argv
     582 * @param argv Array of mrb_value to initialize the object
    512583 * @return [mrb_value] The newly initialized object
    513584 */
     
    520591}
    521592
    522 MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
    523 
    524593/**
    525594 * Creates a new instance of Class, Class.
     
    537606 *       }
    538607 *
    539  * @param [mrb_state*] mrb The current mruby state.
    540  * @param [struct RClass *] super The super class or parent.
     608 * @param mrb The current mruby state.
     609 * @param super The super class or parent.
    541610 * @return [struct RClass *] Reference to the new class.
    542611 */
     
    554623 *      }
    555624 *
    556  * @param [mrb_state*] mrb The current mruby state.
     625 * @param mrb The current mruby state.
    557626 * @return [struct RClass *] Reference to the new module.
    558627 */
     
    581650 *      }
    582651 *
    583  * @param [mrb_state*] mrb The current mruby state.
    584  * @param [const char *] name A string representing the name of the class.
     652 * @param mrb The current mruby state.
     653 * @param name A string representing the name of the class.
    585654 * @return [mrb_bool] A boolean value.
    586655 */
     
    589658/**
    590659 * Gets a class.
    591  * @param [mrb_state*] mrb The current mruby state.
    592  * @param [const char *] name The name of the class.
     660 * @param mrb The current mruby state.
     661 * @param name The name of the class.
    593662 * @return [struct RClass *] A reference to the class.
    594663*/
     
    597666/**
    598667 * Gets a exception class.
    599  * @param [mrb_state*] mrb The current mruby state.
    600  * @param [const char *] name The name of the class.
     668 * @param mrb The current mruby state.
     669 * @param name The name of the class.
    601670 * @return [struct RClass *] A reference to the class.
    602671*/
     
    627696 *      }
    628697 *
    629  * @param [mrb_state*] mrb The current mruby state.
    630  * @param [struct RClass *] outer The name of the outer class.
    631  * @param [const char *] name A string representing the name of the inner class.
     698 * @param mrb The current mruby state.
     699 * @param outer The name of the outer class.
     700 * @param name A string representing the name of the inner class.
    632701 * @return [mrb_bool] A boolean value.
    633702 */
     
    636705/**
    637706 * Gets a child class.
    638  * @param [mrb_state*] mrb The current mruby state.
    639  * @param [struct RClass *] outer The name of the parent class.
    640  * @param [const char *] name The name of the class.
     707 * @param mrb The current mruby state.
     708 * @param outer The name of the parent class.
     709 * @param name The name of the class.
    641710 * @return [struct RClass *] A reference to the class.
    642711*/
     
    645714/**
    646715 * Gets a module.
    647  * @param [mrb_state*] mrb The current mruby state.
    648  * @param [const char *] name The name of the module.
     716 * @param mrb The current mruby state.
     717 * @param name The name of the module.
    649718 * @return [struct RClass *] A reference to the module.
    650719*/
     
    653722/**
    654723 * Gets a module defined under another module.
    655  * @param [mrb_state*] mrb The current mruby state.
    656  * @param [struct RClass *] outer The name of the outer module.
    657  * @param [const char *] name The name of the module.
     724 * @param mrb The current mruby state.
     725 * @param outer The name of the outer module.
     726 * @param name The name of the module.
    658727 * @return [struct RClass *] A reference to the module.
    659728*/
    660729MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
     730/* a function to raise NotImplementedError with current method name */
     731MRB_API void mrb_notimplement(mrb_state*);
     732/* a function to be replacement of unimplemented method */
    661733MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value);
    662734
     
    666738 * Equivalent to:
    667739 *   Object#dup
    668  * @param [mrb_state*] mrb The current mruby state.
    669  * @param [mrb_value] obj Object to be duplicate.
     740 * @param mrb The current mruby state.
     741 * @param obj Object to be duplicate.
    670742 * @return [mrb_value] The newly duplicated object.
    671743 */
    672744MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
    673 MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method);
    674745
    675746/**
     
    708779 *      }
    709780 *
    710  * @param [mrb_state*] mrb The current mruby state.
    711  * @param [struct RClass *] c A reference to a class.
    712  * @param [mrb_sym] mid A symbol referencing a method id.
     781 * @param mrb The current mruby state.
     782 * @param c A reference to a class.
     783 * @param mid A symbol referencing a method id.
    713784 * @return [mrb_bool] A boolean value.
    714785 */
     
    718789 * Defines a new class under a given module
    719790 *
    720  * @param [mrb_state*] mrb The current mruby state.
    721  * @param [struct RClass *] outer Reference to the module under which the new class will be defined
    722  * @param [const char *] name The name of the defined class
    723  * @param [struct RClass *] super The new class parent
     791 * @param mrb The current mruby state.
     792 * @param outer Reference to the module under which the new class will be defined
     793 * @param name The name of the defined class
     794 * @param super The new class parent
    724795 * @return [struct RClass *] Reference to the newly defined class
    725796 * @see mrb_define_class
     
    738809
    739810/**
    740  * Funtion takes n optional arguments
     811 * Function takes n optional arguments
    741812 *
    742813 * @param n
     
    746817
    747818/**
    748  * Funtion takes n1 mandatory arguments and n2 optional arguments
     819 * Function takes n1 mandatory arguments and n2 optional arguments
    749820 *
    750821 * @param n1
     
    784855 * Must be a C string composed of the following format specifiers:
    785856 *
    786  * | char | Ruby type      | C types           | Notes                                               |
     857 * | char | Ruby type      | C types           | Notes                                              |
    787858 * |:----:|----------------|-------------------|----------------------------------------------------|
    788859 * | `o`  | {Object}       | {mrb_value}       | Could be used to retrieve any type of argument     |
     
    791862 * | `A`  | {Array}        | {mrb_value}       | when `!` follows, the value may be `nil`           |
    792863 * | `H`  | {Hash}         | {mrb_value}       | when `!` follows, the value may be `nil`           |
    793  * | `s`  | {String}       | char *, {mrb_int} |  Receive two arguments; `s!` gives (`NULL`,`0`) for `nil`       |
     864 * | `s`  | {String}       | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil`        |
    794865 * | `z`  | {String}       | char *            | `NULL` terminated string; `z!` gives `NULL` for `nil`           |
    795866 * | `a`  | {Array}        | {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` |
    796  * | `f`  | {Float}        | {mrb_float}       |                                                    |
    797  * | `i`  | {Integer}      | {mrb_int}         |                                                    |
     867 * | `f`  | {Fixnum}/{Float} | {mrb_float}       |                                                    |
     868 * | `i`  | {Fixnum}/{Float} | {mrb_int}         |                                                    |
    798869 * | `b`  | boolean        | {mrb_bool}        |                                                    |
    799  * | `n`  | {Symbol}       | {mrb_sym}         |                                                    |
    800  * | `&`  | block          | {mrb_value}       |                                                    |
    801  * | `*`  | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array.  |
    802  * | &vert; | optional     |                   | After this spec following specs would be optional. |
     870 * | `n`  | {String}/{Symbol} | {mrb_sym}         |                                                    |
     871 * | `d`  | data           | void *, {mrb_data_type} const | 2nd argument will be used to check data type so it won't be modified; when `!` follows, the value may be `nil` |
     872 * | `I`  | inline struct  | void *          |                                                    |
     873 * | `&`  | block          | {mrb_value}       | &! raises exception if no block given.             |
     874 * | `*`  | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array; `*!` avoid copy of the stack.  |
     875 * | <code>\|</code> | optional     |                   | After this spec following specs would be optional. |
    803876 * | `?`  | optional given | {mrb_bool}        | `TRUE` if preceding argument is given. Used to check optional argument is given. |
     877 * | `:`  | keyword args   | {mrb_kwargs} const | Get keyword arguments. @see mrb_kwargs |
    804878 *
    805879 * @see mrb_get_args
     
    808882
    809883/**
     884 * Get keyword arguments by `mrb_get_args()` with `:` specifier.
     885 *
     886 * `mrb_kwargs::num` indicates that the number of keyword values.
     887 *
     888 * `mrb_kwargs::values` is an object array, and the keyword argument corresponding to the string array is assigned.
     889 * Note that `undef` is assigned if there is no keyword argument corresponding to `mrb_kwargs::optional`.
     890 *
     891 * `mrb_kwargs::table` accepts a string array.
     892 *
     893 * `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the string array are required.
     894 *
     895 * `mrb_kwargs::rest` is the remaining keyword argument that can be accepted as `**rest` in Ruby.
     896 * If `NULL` is specified, `ArgumentError` is raised when there is an undefined keyword.
     897 *
     898 * Examples:
     899 *
     900 *      // def method(a: 1, b: 2)
     901 *
     902 *      uint32_t kw_num = 2;
     903 *      const char *kw_names[kw_num] = { "a", "b" };
     904 *      uint32_t kw_required = 0;
     905 *      mrb_value kw_values[kw_num];
     906 *      const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, NULL };
     907 *
     908 *      mrb_get_args(mrb, ":", &kwargs);
     909 *      if (mrb_undef_p(kw_values[0])) { kw_values[0] = mrb_fixnum_value(1); }
     910 *      if (mrb_undef_p(kw_values[1])) { kw_values[1] = mrb_fixnum_value(2); }
     911 *
     912 *
     913 *      // def method(str, x:, y: 2, z: "default string", **opts)
     914 *
     915 *      mrb_value str, kw_rest;
     916 *      uint32_t kw_num = 3;
     917 *      const char *kw_names[kw_num] = { "x", "y", "z" };
     918 *      uint32_t kw_required = 1;
     919 *      mrb_value kw_values[kw_num];
     920 *      const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, &kw_rest };
     921 *
     922 *      mrb_get_args(mrb, "S:", &str, &kwargs);
     923 *      // or: mrb_get_args(mrb, ":S", &kwargs, &str);
     924 *      if (mrb_undef_p(kw_values[1])) { kw_values[1] = mrb_fixnum_value(2); }
     925 *      if (mrb_undef_p(kw_values[2])) { kw_values[2] = mrb_str_new_cstr(mrb, "default string"); }
     926 */
     927typedef struct mrb_kwargs mrb_kwargs;
     928
     929struct mrb_kwargs
     930{
     931  uint32_t num;
     932  mrb_value *values;
     933  const char *const *table;
     934  uint32_t required;
     935  mrb_value *rest;
     936};
     937
     938/**
    810939 * Retrieve arguments from mrb_state.
    811940 *
    812  * When applicable, implicit conversions (such as `to_str`, `to_ary`, `to_hash`) are
    813  * applied to received arguments.
    814  * Used inside a function of mrb_func_t type.
    815  *
    816941 * @param mrb The current MRuby state.
    817  * @param format [mrb_args_format] is a list of format specifiers
     942 * @param format is a list of format specifiers
    818943 * @param ... The passing variadic arguments must be a pointer of retrieving type.
    819944 * @return the number of arguments retrieved.
    820945 * @see mrb_args_format
     946 * @see mrb_kwargs
    821947 */
    822948MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...);
    823949
    824 static inline mrb_sym
     950MRB_INLINE mrb_sym
    825951mrb_get_mid(mrb_state *mrb) /* get method symbol */
    826952{
     
    828954}
    829955
    830 static inline int
    831 mrb_get_argc(mrb_state *mrb) /* get argc */
    832 {
    833   return mrb->c->ci->argc;
    834 }
     956/**
     957 * Retrieve number of arguments from mrb_state.
     958 *
     959 * Correctly handles *splat arguments.
     960 */
     961MRB_API mrb_int mrb_get_argc(mrb_state *mrb);
     962
     963MRB_API mrb_value* mrb_get_argv(mrb_state *mrb);
    835964
    836965/* `strlen` for character string literals (use with caution or `strlen` instead)
     
    845974 * Call existing ruby functions.
    846975 *
     976 * Example:
     977 *
    847978 *      #include <stdio.h>
    848979 *      #include <mruby.h>
     
    861992 *        fclose(fp);
    862993 *        mrb_close(mrb);
    863  *       }
    864  * @param [mrb_state*] mrb_state* The current mruby state.
    865  * @param [mrb_value] mrb_value A reference to an mruby value.
    866  * @param [const char*] const char* The name of the method.
    867  * @param [mrb_int] mrb_int The number of arguments the method has.
    868  * @param [...] ... Variadic values(not type safe!).
    869  * @return [mrb_value] mrb_value mruby function value.
    870  */
    871 MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...);
     994 *      }
     995 *
     996 * @param mrb The current mruby state.
     997 * @param val A reference to an mruby value.
     998 * @param name The name of the method.
     999 * @param argc The number of arguments the method has.
     1000 * @param ... Variadic values(not type safe!).
     1001 * @return [mrb_value] mruby function value.
     1002 */
     1003MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, mrb_int argc, ...);
    8721004/**
    8731005 * Call existing ruby functions. This is basically the type safe version of mrb_funcall.
     
    8911023 *        mrb_close(mrb);
    8921024 *       }
    893  * @param [mrb_state*] mrb_state* The current mruby state.
    894  * @param [mrb_value] mrb_value A reference to an mruby value.
    895  * @param [mrb_sym] mrb_sym The symbol representing the method.
    896  * @param [mrb_int] mrb_int The number of arguments the method has.
    897  * @param [const mrb_value*] mrb_value* Pointer to the object.
     1025 * @param mrb The current mruby state.
     1026 * @param val A reference to an mruby value.
     1027 * @param name_sym The symbol representing the method.
     1028 * @param argc The number of arguments the method has.
     1029 * @param obj Pointer to the object.
    8981030 * @return [mrb_value] mrb_value mruby function value.
    8991031 * @see mrb_funcall
    9001032 */
    901 MRB_API mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*);
     1033MRB_API mrb_value mrb_funcall_argv(mrb_state *mrb, mrb_value val, mrb_sym name, mrb_int argc, const mrb_value *argv);
    9021034/**
    9031035 * Call existing ruby functions with a block.
    9041036 */
    905 MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*, mrb_value);
     1037MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym name, mrb_int argc, const mrb_value *argv, mrb_value block);
    9061038/**
    9071039 * Create a symbol
     1040 *
     1041 * Example:
    9081042 *
    9091043 *     # Ruby style:
     
    9121046 *     // C style:
    9131047 *     mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); //  => :pizza
    914  * @param [mrb_state*] mrb_state* The current mruby state.
    915  * @param [const char*] const char* The name of the method.
     1048 *
     1049 * @param mrb The current mruby state.
     1050 * @param str The string to be symbolized
    9161051 * @return [mrb_sym] mrb_sym A symbol.
    9171052 */
    918 MRB_API mrb_sym mrb_intern_cstr(mrb_state*,const char*);
     1053MRB_API mrb_sym mrb_intern_cstr(mrb_state *mrb, const char* str);
    9191054MRB_API mrb_sym mrb_intern(mrb_state*,const char*,size_t);
    9201055MRB_API mrb_sym mrb_intern_static(mrb_state*,const char*,size_t);
     
    9241059MRB_API mrb_value mrb_check_intern(mrb_state*,const char*,size_t);
    9251060MRB_API mrb_value mrb_check_intern_str(mrb_state*,mrb_value);
    926 MRB_API const char *mrb_sym2name(mrb_state*,mrb_sym);
    927 MRB_API const char *mrb_sym2name_len(mrb_state*,mrb_sym,mrb_int*);
    928 MRB_API mrb_value mrb_sym2str(mrb_state*,mrb_sym);
     1061MRB_API const char *mrb_sym_name(mrb_state*,mrb_sym);
     1062MRB_API const char *mrb_sym_name_len(mrb_state*,mrb_sym,mrb_int*);
     1063MRB_API const char *mrb_sym_dump(mrb_state*,mrb_sym);
     1064MRB_API mrb_value mrb_sym_str(mrb_state*,mrb_sym);
     1065#define mrb_sym2name(mrb,sym) mrb_sym_name(mrb,sym)
     1066#define mrb_sym2name_len(mrb,sym,len) mrb_sym_name_len(mrb,sym,len)
     1067#define mrb_sym2str(mrb,sym) mrb_sym_str(mrb,sym)
    9291068
    9301069MRB_API void *mrb_malloc(mrb_state*, size_t);         /* raise RuntimeError if no mem */
     
    9451084#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
    9461085
     1086MRB_API mrb_value mrb_obj_freeze(mrb_state*, mrb_value);
     1087#define mrb_str_new_frozen(mrb,p,len) mrb_obj_freeze(mrb,mrb_str_new(mrb,p,len))
     1088#define mrb_str_new_cstr_frozen(mrb,p) mrb_obj_freeze(mrb,mrb_str_new_cstr(mrb,p))
     1089#define mrb_str_new_static_frozen(mrb,p,len) mrb_obj_freeze(mrb,mrb_str_new_static(mrb,p,len))
     1090#define mrb_str_new_lit_frozen(mrb,lit) mrb_obj_freeze(mrb,mrb_str_new_lit(mrb,lit))
     1091
    9471092#ifdef _WIN32
    948 char* mrb_utf8_from_locale(const char *p, size_t len);
    949 char* mrb_locale_from_utf8(const char *p, size_t len);
     1093MRB_API char* mrb_utf8_from_locale(const char *p, int len);
     1094MRB_API char* mrb_locale_from_utf8(const char *p, int len);
    9501095#define mrb_locale_free(p) free(p)
    9511096#define mrb_utf8_free(p) free(p)
    9521097#else
    953 #define mrb_utf8_from_locale(p, l) (p)
    954 #define mrb_locale_from_utf8(p, l) (p)
     1098#define mrb_utf8_from_locale(p, l) ((char*)(p))
     1099#define mrb_locale_from_utf8(p, l) ((char*)(p))
    9551100#define mrb_locale_free(p)
    9561101#define mrb_utf8_free(p)
     
    10071152MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*);
    10081153
    1009 MRB_API mrb_value mrb_top_self(mrb_state *);
    1010 MRB_API mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
    1011 MRB_API mrb_value mrb_top_run(mrb_state*, struct RProc*, mrb_value, unsigned int);
    1012 MRB_API mrb_value mrb_vm_run(mrb_state*, struct RProc*, mrb_value, unsigned int);
    1013 MRB_API mrb_value mrb_vm_exec(mrb_state*, struct RProc*, mrb_code*);
     1154MRB_API mrb_value mrb_top_self(mrb_state *mrb);
     1155MRB_API mrb_value mrb_run(mrb_state *mrb, struct RProc* proc, mrb_value self);
     1156MRB_API mrb_value mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
     1157MRB_API mrb_value mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
     1158MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *iseq);
    10141159/* compatibility macros */
    10151160#define mrb_toplevel_run_keep(m,p,k) mrb_top_run((m),(p),mrb_top_self(m),(k))
     
    10211166MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name);
    10221167
    1023 MRB_API mrb_bool mrb_obj_eq(mrb_state*, mrb_value, mrb_value);
    1024 MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
     1168MRB_API mrb_bool mrb_obj_eq(mrb_state *mrb, mrb_value a, mrb_value b);
     1169MRB_API mrb_bool mrb_obj_equal(mrb_state *mrb, mrb_value a, mrb_value b);
    10251170MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
    1026 MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base);
     1171MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base);
    10271172MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
     1173#ifndef MRB_WITHOUT_FLOAT
    10281174MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
     1175#endif
    10291176MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
    10301177MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
     1178/* mrb_cmp(mrb, obj1, obj2): 1:0:-1; -2 for error */
     1179MRB_API mrb_int mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
     1180
     1181MRB_INLINE int
     1182mrb_gc_arena_save(mrb_state *mrb)
     1183{
     1184  return mrb->gc.arena_idx;
     1185}
     1186
     1187MRB_INLINE void
     1188mrb_gc_arena_restore(mrb_state *mrb, int idx)
     1189{
     1190  mrb->gc.arena_idx = idx;
     1191}
    10311192
    10321193MRB_API void mrb_garbage_collect(mrb_state*);
    10331194MRB_API void mrb_full_gc(mrb_state*);
    10341195MRB_API void mrb_incremental_gc(mrb_state *);
    1035 MRB_API int mrb_gc_arena_save(mrb_state*);
    1036 MRB_API void mrb_gc_arena_restore(mrb_state*,int);
    10371196MRB_API void mrb_gc_mark(mrb_state*,struct RBasic*);
    10381197#define mrb_gc_mark_value(mrb,val) do {\
     
    10771236MRB_API mrb_noreturn void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...);
    10781237MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...);
     1238MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj);
     1239MRB_API mrb_noreturn void mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max);
    10791240MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...);
    10801241MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...);
    10811242MRB_API void mrb_print_backtrace(mrb_state *mrb);
    10821243MRB_API void mrb_print_error(mrb_state *mrb);
     1244/* function for `raisef` formatting */
     1245MRB_API mrb_value mrb_vformat(mrb_state *mrb, const char *format, va_list ap);
    10831246
    10841247/* macros to get typical exception objects
     
    10981261#define E_LOCALJUMP_ERROR           (mrb_exc_get(mrb, "LocalJumpError"))
    10991262#define E_REGEXP_ERROR              (mrb_exc_get(mrb, "RegexpError"))
     1263#define E_FROZEN_ERROR              (mrb_exc_get(mrb, "FrozenError"))
    11001264
    11011265#define E_NOTIMP_ERROR              (mrb_exc_get(mrb, "NotImplementedError"))
     1266#ifndef MRB_WITHOUT_FLOAT
    11021267#define E_FLOATDOMAIN_ERROR         (mrb_exc_get(mrb, "FloatDomainError"))
     1268#endif
    11031269
    11041270#define E_KEY_ERROR                 (mrb_exc_get(mrb, "KeyError"))
     
    11221288MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
    11231289#define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val))
     1290/* string type checking (contrary to the name, it doesn't convert) */
     1291MRB_API mrb_value mrb_to_str(mrb_state *mrb, mrb_value val);
    11241292MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
     1293
     1294MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o)
     1295{
     1296  if (mrb_frozen_p((struct RBasic*)o)) mrb_frozen_error(mrb, o);
     1297}
    11251298
    11261299typedef enum call_type {
     
    11311304} call_type;
    11321305
    1133 MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2);
     1306MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *c, const char *a, const char *b);
    11341307MRB_API const char *mrb_class_name(mrb_state *mrb, struct RClass* klass);
    11351308MRB_API void mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val);
     
    11421315
    11431316
    1144 /*
     1317/**
    11451318 * Resume a Fiber
    11461319 *
    1147  * @mrbgem mruby-fiber
     1320 * Implemented in mruby-fiber
    11481321 */
    11491322MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int argc, const mrb_value *argv);
    11501323
    1151 /*
     1324/**
    11521325 * Yield a Fiber
    11531326 *
    1154  * @mrbgem mruby-fiber
     1327 * Implemented in mruby-fiber
    11551328 */
    11561329MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
    11571330
    1158 /*
     1331/**
     1332 * Check if a Fiber is alive
     1333 *
     1334 * Implemented in mruby-fiber
     1335 */
     1336MRB_API mrb_value mrb_fiber_alive_p(mrb_state *mrb, mrb_value fib);
     1337
     1338/**
    11591339 * FiberError reference
    11601340 *
    1161  * @mrbgem mruby-fiber
     1341 * Implemented in mruby-fiber
    11621342 */
    11631343#define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError"))
     1344MRB_API void mrb_stack_extend(mrb_state*, mrb_int);
    11641345
    11651346/* memory pool implementation */
     
    11701351MRB_API void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen);
    11711352MRB_API mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t);
     1353/* temporary memory allocation, only effective while GC arena is kept */
    11721354MRB_API void* mrb_alloca(mrb_state *mrb, size_t);
    11731355
     
    11841366#undef memcpy
    11851367#undef memset
    1186 static inline void*
     1368static void*
    11871369mrbmemcpy(void *dst, const void *src, size_t n)
    11881370{
    1189   char *d = dst;
    1190   const char *s = src;
     1371  char *d = (char*)dst;
     1372  const char *s = (const char*)src;
    11911373  while (n--)
    11921374    *d++ = *s++;
     
    11951377#define memcpy(a,b,c) mrbmemcpy(a,b,c)
    11961378
    1197 static inline void*
     1379static void*
    11981380mrbmemset(void *s, int c, size_t n)
    11991381{
    1200   char *t = s;
     1382  char *t = (char*)s;
    12011383  while (n--)
    12021384    *t++ = c;
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/array.h

    r331 r439  
    1 /*
    2 ** mruby/array.h - Array class
     1/**
     2** @file mruby/array.h - Array class
    33**
    44** See Copyright Notice in mruby.h
     
    1818typedef struct mrb_shared_array {
    1919  int refcnt;
    20   mrb_int len;
     20  mrb_ssize len;
    2121  mrb_value *ptr;
    2222} mrb_shared_array;
    2323
     24#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
    2425struct RArray {
    2526  MRB_OBJECT_HEADER;
    26   mrb_int len;
    2727  union {
    28     mrb_int capa;
    29     mrb_shared_array *shared;
    30   } aux;
    31   mrb_value *ptr;
     28    struct {
     29      mrb_ssize len;
     30      union {
     31        mrb_ssize capa;
     32        mrb_shared_array *shared;
     33      } aux;
     34      mrb_value *ptr;
     35    } heap;
     36    void *ary[3];
     37  } as;
    3238};
    3339
     
    3642#define RARRAY(v)  ((struct RArray*)(mrb_ptr(v)))
    3743
    38 #define RARRAY_LEN(a) (RARRAY(a)->len)
    39 #define RARRAY_PTR(a) ((const mrb_value*)RARRAY(a)->ptr)
     44#define MRB_ARY_EMBED_MASK  7
     45#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK)
     46#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
     47#define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
     48#define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
     49#define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as.ary))
     50
     51#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
     52#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
     53#define RARRAY_LEN(a) ARY_LEN(RARRAY(a))
     54#define RARRAY_PTR(a) ARY_PTR(RARRAY(a))
     55#define ARY_SET_LEN(a,n) do {\
     56  if (ARY_EMBED_P(a)) {\
     57    mrb_assert((n) <= MRB_ARY_EMBED_LEN_MAX); \
     58    ARY_SET_EMBED_LEN(a,n);\
     59  }\
     60  else\
     61    (a)->as.heap.len = (n);\
     62} while (0)
     63#define ARY_CAPA(a) (ARY_EMBED_P(a)?MRB_ARY_EMBED_LEN_MAX:(a)->as.heap.aux.capa)
    4064#define MRB_ARY_SHARED      256
    4165#define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED)
     
    176200 */
    177201MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other);
     202MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self);
    178203MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
    179204
    180205/*
    181  * Unshift an element into an array
     206 * Unshift an element into the array
    182207 *
    183208 * Equivalent to:
     
    190215 */
    191216MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
     217
     218/*
     219 * Get nth element in the array
     220 *
     221 * Equivalent to:
     222 *
     223 *     ary[offset]
     224 *
     225 * @param ary The target array.
     226 * @param offset The element position (negative counts from the tail).
     227 */
    192228MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
     229
     230/*
     231 * Replace subsequence of an array.
     232 *
     233 * Equivalent to:
     234 *
     235 *      ary.shift
     236 *
     237 * @param mrb The mruby state reference.
     238 * @param self The array from which the value will be shifted.
     239 * @param head Beginning position of a replacement subsequence.
     240 * @param len Length of a replacement subsequence.
     241 * @param rpl The array of replacement elements.
     242 * @return The receiver array.
     243 */
     244MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value self, mrb_int head, mrb_int len, mrb_value rpl);
    193245
    194246/*
     
    206258
    207259/*
    208  * Removes all elements from this array
     260 * Removes all elements from the array
    209261 *
    210262 * Equivalent to:
     
    240292MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
    241293
    242 static inline mrb_int
    243 mrb_ary_len(mrb_state *mrb, mrb_value ary)
    244 {
    245   (void)mrb;
    246   mrb_assert(mrb_array_p(ary));
    247   return RARRAY_LEN(ary);
    248 }
    249 
    250 static inline mrb_value
    251 ary_elt(mrb_value ary, mrb_int offset)
    252 {
    253   if (offset < 0 || RARRAY_LEN(ary) <= offset) {
    254     return mrb_nil_value();
    255   }
    256   return RARRAY_PTR(ary)[offset];
    257 }
    258 
    259294MRB_END_DECL
    260295
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/boxing_nan.h

    r331 r439  
    1 /*
    2 ** mruby/boxing_nan.h - nan boxing mrb_value definition
     1/**
     2** @file mruby/boxing_nan.h - nan boxing mrb_value definition
    33**
    44** See Copyright Notice in mruby.h
     
    1212#endif
    1313
     14#ifdef MRB_WITHOUT_FLOAT
     15# error ---->> MRB_NAN_BOXING and MRB_WITHOUT_FLOAT conflict <<----
     16#endif
     17
    1418#ifdef MRB_INT64
    1519# error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<----
     
    1721
    1822#define MRB_FIXNUM_SHIFT 0
    19 #define MRB_TT_HAS_BASIC MRB_TT_OBJECT
    20 
    21 #ifdef MRB_ENDIAN_BIG
    22 #define MRB_ENDIAN_LOHI(a,b) a b
    23 #else
    24 #define MRB_ENDIAN_LOHI(a,b) b a
    25 #endif
     23#define MRB_SYMBOL_SHIFT 0
    2624
    2725/* value representation by nan-boxing:
     
    7876
    7977#define SET_FLOAT_VALUE(mrb,r,v) do { \
    80   if (v != v) { \
     78  if ((v) != (v)) { \
    8179    (r).value.ttt = 0x7ff80000; \
    8280    (r).value.i = 0; \
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/boxing_no.h

    r321 r439  
    1 /*
    2 ** mruby/boxing_no.h - unboxed mrb_value definition
     1/**
     2** @file mruby/boxing_no.h - unboxed mrb_value definition
    33**
    44** See Copyright Notice in mruby.h
     
    99
    1010#define MRB_FIXNUM_SHIFT 0
    11 #define MRB_TT_HAS_BASIC MRB_TT_OBJECT
     11#define MRB_SYMBOL_SHIFT 0
     12
     13union mrb_value_union {
     14#ifndef MRB_WITHOUT_FLOAT
     15  mrb_float f;
     16#endif
     17  void *p;
     18  mrb_int i;
     19  mrb_sym sym;
     20};
    1221
    1322typedef struct mrb_value {
    14   union {
    15     mrb_float f;
    16     void *p;
    17     mrb_int i;
    18     mrb_sym sym;
    19   } value;
     23  union mrb_value_union value;
    2024  enum mrb_vtype tt;
    2125} mrb_value;
    2226
     27#ifndef MRB_WITHOUT_FLOAT
    2328#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
     29#endif
    2430
    2531#define mrb_ptr(o)      (o).value.p
    2632#define mrb_cptr(o)     mrb_ptr(o)
     33#ifndef MRB_WITHOUT_FLOAT
    2734#define mrb_float(o)    (o).value.f
     35#endif
    2836#define mrb_fixnum(o)   (o).value.i
    2937#define mrb_symbol(o)   (o).value.sym
     
    4048#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
    4149#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
     50#ifndef MRB_WITHOUT_FLOAT
    4251#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
     52#endif
    4353#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
    4454#define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/boxing_word.h

    r331 r439  
    1 /*
    2 ** mruby/boxing_word.h - word boxing mrb_value definition
     1/**
     2** @file mruby/boxing_word.h - word boxing mrb_value definition
    33**
    44** See Copyright Notice in mruby.h
     
    88#define MRUBY_BOXING_WORD_H
    99
    10 #if defined(MRB_INT16)
    11 # error MRB_INT16 is too small for MRB_WORD_BOXING.
    12 #endif
    13 
    1410#if defined(MRB_INT64) && !defined(MRB_64BIT)
    1511#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
    1612#endif
    1713
     14#ifndef MRB_WITHOUT_FLOAT
    1815struct RFloat {
    1916  MRB_OBJECT_HEADER;
    2017  mrb_float f;
    2118};
     19#endif
    2220
    2321struct RCptr {
     
    2624};
    2725
    28 #define MRB_FIXNUM_SHIFT 1
    29 #define MRB_TT_HAS_BASIC MRB_TT_FLOAT
    30 
    3126enum mrb_special_consts {
    32   MRB_Qnil    = 0,
    33   MRB_Qfalse  = 2,
    34   MRB_Qtrue   = 4,
    35   MRB_Qundef  = 6,
     27  MRB_Qnil    =  0,
     28  MRB_Qfalse  =  4,
     29  MRB_Qtrue   = 12,
     30  MRB_Qundef  = 20,
    3631};
    3732
    38 #define MRB_FIXNUM_FLAG   0x01
    39 #define MRB_SYMBOL_FLAG   0x0e
    40 #define MRB_SPECIAL_SHIFT 8
     33#if defined(MRB_64BIT) && defined(MRB_INT32)
     34#define MRB_FIXNUM_SHIFT        0
     35#else
     36#define MRB_FIXNUM_SHIFT        BOXWORD_FIXNUM_SHIFT
     37#endif
     38#define MRB_SYMBOL_SHIFT        BOXWORD_SYMBOL_SHIFT
    4139
     40#define BOXWORD_FIXNUM_BIT_POS  1
     41#define BOXWORD_SYMBOL_BIT_POS  2
     42#define BOXWORD_FIXNUM_SHIFT    BOXWORD_FIXNUM_BIT_POS
     43#ifdef MRB_64BIT
     44#define BOXWORD_SYMBOL_SHIFT    0
     45#else
     46#define BOXWORD_SYMBOL_SHIFT    BOXWORD_SYMBOL_BIT_POS
     47#endif
     48#define BOXWORD_FIXNUM_FLAG     (1 << (BOXWORD_FIXNUM_BIT_POS - 1))
     49#define BOXWORD_SYMBOL_FLAG     (1 << (BOXWORD_SYMBOL_BIT_POS - 1))
     50#define BOXWORD_FIXNUM_MASK     ((1 << BOXWORD_FIXNUM_BIT_POS) - 1)
     51#define BOXWORD_SYMBOL_MASK     ((1 << BOXWORD_SYMBOL_BIT_POS) - 1)
     52#define BOXWORD_IMMEDIATE_MASK  0x07
     53
     54#define BOXWORD_SHIFT_VALUE(o,n,t) \
     55  (t)(((long)(o).w) >> BOXWORD_##n##_SHIFT)
     56#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \
     57  ((o).w = (((unsigned long)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
     58#define BOXWORD_SHIFT_VALUE_P(o,n) \
     59  (((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
     60#define BOXWORD_OBJ_TYPE_P(o,n) \
     61  (!mrb_immediate_p(o) && (o).value.bp->tt == MRB_TT_##n)
     62
     63/*
     64 * mrb_value representation:
     65 *
     66 *   nil   : ...0000 0000 (all bits are 0)
     67 *   false : ...0000 0100 (mrb_fixnum(v) != 0)
     68 *   true  : ...0000 1100
     69 *   undef : ...0001 0100
     70 *   fixnum: ...IIII III1
     71 *   symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU)
     72 *   object: ...PPPP P000 (any bits are 1)
     73 */
    4274typedef union mrb_value {
    4375  union {
    4476    void *p;
     77#ifdef MRB_64BIT
     78    /* use struct to avoid bit shift. */
    4579    struct {
    46       unsigned int i_flag : MRB_FIXNUM_SHIFT;
    47       mrb_int i : (MRB_INT_BIT - MRB_FIXNUM_SHIFT);
     80      MRB_ENDIAN_LOHI(
     81        mrb_sym sym;
     82        ,uint32_t sym_flag;
     83      )
    4884    };
    49     struct {
    50       unsigned int sym_flag : MRB_SPECIAL_SHIFT;
    51       mrb_sym sym : (sizeof(mrb_sym) * CHAR_BIT);
    52     };
     85#endif
    5386    struct RBasic *bp;
     87#ifndef MRB_WITHOUT_FLOAT
    5488    struct RFloat *fp;
     89#endif
    5590    struct RCptr *vp;
    5691  } value;
     
    5994
    6095MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*);
     96#ifndef MRB_WITHOUT_FLOAT
    6197MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float);
    6298MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
     99#endif
    63100
     101#ifndef MRB_WITHOUT_FLOAT
    64102#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f)
     103#endif
    65104
    66105#define mrb_ptr(o)     (o).value.p
    67106#define mrb_cptr(o)    (o).value.vp->p
     107#ifndef MRB_WITHOUT_FLOAT
    68108#define mrb_float(o)   (o).value.fp->f
    69 #define mrb_fixnum(o)  ((mrb_int)(o).value.i)
     109#endif
     110#define mrb_fixnum(o)  BOXWORD_SHIFT_VALUE(o, FIXNUM, mrb_int)
     111#ifdef MRB_64BIT
    70112#define mrb_symbol(o)  (o).value.sym
     113#else
     114#define mrb_symbol(o)  BOXWORD_SHIFT_VALUE(o, SYMBOL, mrb_sym)
     115#endif
     116#define mrb_bool(o)    (((o).w & ~(unsigned long)MRB_Qfalse) != 0)
    71117
    72 static inline enum mrb_vtype
     118#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil)
     119#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM)
     120#ifdef MRB_64BIT
     121#define mrb_symbol_p(o) ((o).value.sym_flag == BOXWORD_SYMBOL_FLAG)
     122#else
     123#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL)
     124#endif
     125#define mrb_undef_p(o) ((o).w == MRB_Qundef)
     126#define mrb_nil_p(o)  ((o).w == MRB_Qnil)
     127#define mrb_false_p(o) ((o).w == MRB_Qfalse)
     128#define mrb_true_p(o)  ((o).w == MRB_Qtrue)
     129#ifndef MRB_WITHOUT_FLOAT
     130#define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT)
     131#endif
     132#define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY)
     133#define mrb_string_p(o) BOXWORD_OBJ_TYPE_P(o, STRING)
     134#define mrb_hash_p(o) BOXWORD_OBJ_TYPE_P(o, HASH)
     135#define mrb_cptr_p(o) BOXWORD_OBJ_TYPE_P(o, CPTR)
     136#define mrb_exception_p(o) BOXWORD_OBJ_TYPE_P(o, EXCEPTION)
     137#define mrb_free_p(o) BOXWORD_OBJ_TYPE_P(o, FREE)
     138#define mrb_object_p(o) BOXWORD_OBJ_TYPE_P(o, OBJECT)
     139#define mrb_class_p(o) BOXWORD_OBJ_TYPE_P(o, CLASS)
     140#define mrb_module_p(o) BOXWORD_OBJ_TYPE_P(o, MODULE)
     141#define mrb_iclass_p(o) BOXWORD_OBJ_TYPE_P(o, ICLASS)
     142#define mrb_sclass_p(o) BOXWORD_OBJ_TYPE_P(o, SCLASS)
     143#define mrb_proc_p(o) BOXWORD_OBJ_TYPE_P(o, PROC)
     144#define mrb_range_p(o) BOXWORD_OBJ_TYPE_P(o, RANGE)
     145#define mrb_file_p(o) BOXWORD_OBJ_TYPE_P(o, FILE)
     146#define mrb_env_p(o) BOXWORD_OBJ_TYPE_P(o, ENV)
     147#define mrb_data_p(o) BOXWORD_OBJ_TYPE_P(o, DATA)
     148#define mrb_fiber_p(o) BOXWORD_OBJ_TYPE_P(o, FIBER)
     149#define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT)
     150#define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK)
     151
     152#ifndef MRB_WITHOUT_FLOAT
     153#define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v))
     154#endif
     155#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v))
     156#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef)
     157#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil)
     158#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse)
     159#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue)
     160#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r))
     161#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
     162#ifdef MRB_64BIT
     163#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = BOXWORD_SYMBOL_FLAG)
     164#else
     165#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n)
     166#endif
     167#define SET_OBJ_VALUE(r,v) ((r).value.p = v)
     168
     169MRB_INLINE enum mrb_vtype
    73170mrb_type(mrb_value o)
    74171{
    75   switch (o.w) {
    76   case MRB_Qfalse:
    77   case MRB_Qnil:
    78     return MRB_TT_FALSE;
    79   case MRB_Qtrue:
    80     return MRB_TT_TRUE;
    81   case MRB_Qundef:
    82     return MRB_TT_UNDEF;
    83   }
    84   if (o.value.i_flag == MRB_FIXNUM_FLAG) {
    85     return MRB_TT_FIXNUM;
    86   }
    87   if (o.value.sym_flag == MRB_SYMBOL_FLAG) {
    88     return MRB_TT_SYMBOL;
    89   }
    90   return o.value.bp->tt;
     172  return !mrb_bool(o)    ? MRB_TT_FALSE :
     173         mrb_true_p(o)   ? MRB_TT_TRUE :
     174         mrb_fixnum_p(o) ? MRB_TT_FIXNUM :
     175         mrb_symbol_p(o) ? MRB_TT_SYMBOL :
     176         mrb_undef_p(o)  ? MRB_TT_UNDEF :
     177         o.value.bp->tt;
    91178}
    92179
    93 #define mrb_bool(o)    ((o).w != MRB_Qnil && (o).w != MRB_Qfalse)
    94 #define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG)
    95 #define mrb_undef_p(o) ((o).w == MRB_Qundef)
    96 #define mrb_nil_p(o)  ((o).w == MRB_Qnil)
    97 
    98 #define BOXWORD_SET_VALUE(o, ttt, attr, v) do { \
    99   switch (ttt) {\
    100   case MRB_TT_FALSE:  (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\
    101   case MRB_TT_TRUE:   (o).w = MRB_Qtrue; break;\
    102   case MRB_TT_UNDEF:  (o).w = MRB_Qundef; break;\
    103   case MRB_TT_FIXNUM: (o).w = 0;(o).value.i_flag = MRB_FIXNUM_FLAG; (o).attr = (v); break;\
    104   case MRB_TT_SYMBOL: (o).w = 0;(o).value.sym_flag = MRB_SYMBOL_FLAG; (o).attr = (v); break;\
    105   default:            (o).w = 0; (o).attr = (v); if ((o).value.bp) (o).value.bp->tt = ttt; break;\
    106   }\
    107 } while (0)
    108 
    109 #define SET_FLOAT_VALUE(mrb,r,v) r = mrb_word_boxing_float_value(mrb, v)
    110 #define SET_CPTR_VALUE(mrb,r,v) r = mrb_word_boxing_cptr_value(mrb, v)
    111 #define SET_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
    112 #define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
    113 #define SET_TRUE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
    114 #define SET_BOOL_VALUE(r,b) BOXWORD_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
    115 #define SET_INT_VALUE(r,n) BOXWORD_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
    116 #define SET_SYM_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
    117 #define SET_OBJ_VALUE(r,v) BOXWORD_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
    118 #define SET_UNDEF_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
    119 
    120180#endif  /* MRUBY_BOXING_WORD_H */
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/class.h

    r331 r439  
    1 /*
    2 ** mruby/class.h - Class class
     1/**
     2** @file mruby/class.h - Class class
    33**
    44** See Copyright Notice in mruby.h
     
    2323
    2424#define mrb_class_ptr(v)    ((struct RClass*)(mrb_ptr(v)))
    25 #define RCLASS_SUPER(v)     (((struct RClass*)(mrb_ptr(v)))->super)
    26 #define RCLASS_IV_TBL(v)    (((struct RClass*)(mrb_ptr(v)))->iv)
    27 #define RCLASS_M_TBL(v)     (((struct RClass*)(mrb_ptr(v)))->mt)
    2825
    29 static inline struct RClass*
     26MRB_INLINE struct RClass*
    3027mrb_class(mrb_state *mrb, mrb_value v)
    3128{
     
    4138  case MRB_TT_FIXNUM:
    4239    return mrb->fixnum_class;
     40#ifndef MRB_WITHOUT_FLOAT
    4341  case MRB_TT_FLOAT:
    4442    return mrb->float_class;
     43#endif
    4544  case MRB_TT_CPTR:
    4645    return mrb->object_class;
     
    5251}
    5352
    54 /* TODO: figure out where to put user flags */
    55 #define MRB_FLAG_IS_FROZEN (1 << 18)
    56 #define MRB_FLAG_IS_PREPENDED (1 << 19)
    57 #define MRB_FLAG_IS_ORIGIN (1 << 20)
     53/* flags:
     54   20: frozen
     55   19: is_prepended
     56   18: is_origin
     57   17: is_inherited (used by method cache)
     58   16: unused
     59   0-15: instance type
     60*/
     61#define MRB_FL_CLASS_IS_PREPENDED (1 << 19)
     62#define MRB_FL_CLASS_IS_ORIGIN (1 << 18)
    5863#define MRB_CLASS_ORIGIN(c) do {\
    59   if (c->flags & MRB_FLAG_IS_PREPENDED) {\
    60     c = c->super;\
    61     while (!(c->flags & MRB_FLAG_IS_ORIGIN)) {\
    62       c = c->super;\
     64  if ((c)->flags & MRB_FL_CLASS_IS_PREPENDED) {\
     65    (c) = (c)->super;\
     66    while (!((c)->flags & MRB_FL_CLASS_IS_ORIGIN)) {\
     67      (c) = (c)->super;\
    6368    }\
    6469  }\
    6570} while (0)
     71#define MRB_FL_CLASS_IS_INHERITED (1 << 17)
    6672#define MRB_INSTANCE_TT_MASK (0xFF)
    67 #define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt)
    68 #define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK)
     73#define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt)))
     74#define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK)
    6975
    7076MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
    7177MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
    72 MRB_API struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
    73 MRB_API struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
    74 MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct RProc *);
     78struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
     79struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
     80MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t);
    7581MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
    76 MRB_API void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b);
     82MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b);
    7783
    78 MRB_API struct RClass *mrb_class_outer_module(mrb_state*, struct RClass *);
    79 MRB_API struct RProc *mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
    80 MRB_API struct RProc *mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
     84MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
     85MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
    8186
    8287MRB_API struct RClass* mrb_class_real(struct RClass* cl);
     88mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
    8389
     90void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
     91mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
     92mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
     93mrb_value mrb_mod_to_s(mrb_state*, mrb_value);
    8494void mrb_gc_mark_mt(mrb_state*, struct RClass*);
    8595size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
    8696void mrb_gc_free_mt(mrb_state*, struct RClass*);
    8797
     98#ifdef MRB_METHOD_CACHE
     99void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c);
     100#else
     101#define mrb_mc_clear_by_class(mrb,c)
     102#endif
     103
    88104MRB_END_DECL
    89105
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/common.h

    r331 r439  
    1 /*
    2 **"common.h - mruby common platform definition"
     1/**
     2** @file common.h - mruby common platform definition"
    33**
    44** See Copyright Notice in mruby.h
     
    88#define MRUBY_COMMON_H
    99
     10#ifdef __APPLE__
     11  #ifndef __TARGETCONDITIONALS__
     12  #include "TargetConditionals.h"
     13  #endif
     14#endif
    1015
    1116#ifdef __cplusplus
     
    1520#else
    1621# define MRB_BEGIN_DECL extern "C" {
    17 # define MRB_END_DECL   }
     22# define MRB_END_DECL }
    1823#endif
    1924#else
     
    3035
    3136/** Declare a function that never returns. */
    32 #if __STDC_VERSION__ >= 201112L
     37#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
    3338# define mrb_noreturn _Noreturn
    3439#elif defined __GNUC__ && !defined __STRICT_ANSI__
     
    5055
    5156/** Declare a function as always inlined. */
    52 #if defined(_MSC_VER)
    53 # define MRB_INLINE static __inline
    54 #else
    55 # define MRB_INLINE static inline
     57#if defined _MSC_VER && _MSC_VER < 1900
     58# ifndef __cplusplus
     59#  define inline __inline
     60# endif
    5661#endif
    57 
     62#define MRB_INLINE static inline
    5863
    5964/** Declare a public MRuby API function. */
     65#ifndef MRB_API
    6066#if defined(MRB_BUILD_AS_DLL)
    6167#if defined(MRB_CORE) || defined(MRB_LIB)
     
    6773# define MRB_API extern
    6874#endif
     75#endif
     76
     77/** Declare mingw versions */
     78#if defined(__MINGW32__) || defined(__MINGW64__)
     79# include <_mingw.h>
     80# if defined(__MINGW64_VERSION_MAJOR)
     81#  define MRB_MINGW64_VERSION  (__MINGW64_VERSION_MAJOR * 1000 + __MINGW64_VERSION_MINOR)
     82# elif defined(__MINGW32_MAJOR_VERSION)
     83#  define MRB_MINGW32_VERSION  (__MINGW32_MAJOR_VERSION * 1000 + __MINGW32_MINOR_VERSION)
     84# endif
     85#endif
    6986
    7087MRB_END_DECL
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/compile.h

    r331 r439  
    1 /*
    2 ** mruby/compile.h - mruby parser
     1/**
     2** @file mruby/compile.h - mruby parser
    33**
    44** See Copyright Notice in mruby.h
     
    2525  int slen;
    2626  char *filename;
    27   short lineno;
     27  uint16_t lineno;
    2828  int (*partial_hook)(struct mrb_parser_state*);
    2929  void *partial_data;
     
    3434  mrb_bool keep_lv:1;
    3535  mrb_bool no_optimize:1;
     36  mrb_bool on_eval:1;
     37
     38  size_t parser_nerr;
    3639} mrbc_context;
    3740
     
    6568/* saved error message */
    6669struct mrb_parser_message {
    67   int lineno;
     70  uint16_t lineno;
    6871  int column;
    6972  char* message;
     
    103106};
    104107
    105 #define MRB_PARSER_TOKBUF_MAX 65536
     108#define MRB_PARSER_TOKBUF_MAX (UINT16_MAX-1)
    106109#define MRB_PARSER_TOKBUF_SIZE 256
    107110
     
    116119#endif
    117120  mrbc_context *cxt;
    118   char const *filename;
    119   int lineno;
     121  mrb_sym filename_sym;
     122  uint16_t lineno;
    120123  int column;
    121124
     
    137140  int tsiz;
    138141
    139   mrb_ast_node *all_heredocs;   /* list of mrb_parser_heredoc_info* */
     142  mrb_ast_node *all_heredocs; /* list of mrb_parser_heredoc_info* */
    140143  mrb_ast_node *heredocs_from_nextline;
    141144  mrb_ast_node *parsing_heredoc;
    142145  mrb_ast_node *lex_strterm_before_heredoc;
    143   mrb_bool heredoc_end_now:1; /* for mirb */
    144146
    145147  void *ylval;
     
    150152
    151153  mrb_bool no_optimize:1;
     154  mrb_bool on_eval:1;
    152155  mrb_bool capture_errors:1;
    153156  struct mrb_parser_message error_buffer[10];
     
    155158
    156159  mrb_sym* filename_table;
    157   size_t filename_table_length;
    158   int current_filename_index;
     160  uint16_t filename_table_length;
     161  uint16_t current_filename_index;
    159162
    160163  struct mrb_jmpbuf* jmp;
     164  mrb_ast_node *nvars;
    161165};
    162166
     
    164168MRB_API void mrb_parser_free(struct mrb_parser_state*);
    165169MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*);
    166 MRB_API double mrb_float_read(const char*, char**);
    167170
    168171MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*);
    169 MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx);
     172MRB_API mrb_sym mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx);
    170173
    171174/* utility functions */
     
    174177#endif
    175178MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
    176 MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mrbc_context*);
     179MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,size_t,mrbc_context*);
    177180MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
    178181MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c);
     
    184187#endif
    185188MRB_API mrb_value mrb_load_string(mrb_state *mrb, const char *s);
    186 MRB_API mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, int len);
     189MRB_API mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, size_t len);
    187190MRB_API mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *cxt);
    188 MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *cxt);
     191MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *cxt);
    189192
    190193/** @} */
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/data.h

    r331 r439  
    1 /*
    2 ** mruby/data.h - Data class
     1/**
     2** @file mruby/data.h - Data class
    33**
    44** See Copyright Notice in mruby.h
     
    4040  mrb_data_object_alloc(mrb,klass,ptr,type)
    4141
    42 #define Data_Make_Struct(mrb,klass,strct,type,sval,data) do { \
    43   sval = mrb_malloc(mrb, sizeof(strct));                     \
    44   { static const strct zero = { 0 }; *sval = zero; };\
    45   data = Data_Wrap_Struct(mrb,klass,type,sval);\
     42#define Data_Make_Struct(mrb,klass,strct,type,sval,data_obj) do { \
     43  (data_obj) = Data_Wrap_Struct(mrb,klass,type,NULL);\
     44  (sval) = (strct *)mrb_malloc(mrb, sizeof(strct));                     \
     45  { static const strct zero = { 0 }; *(sval) = zero; };\
     46  (data_obj)->data = (sval);\
    4647} while (0)
    4748
     
    6364} while (0)
    6465
    65 static inline void
     66MRB_INLINE void
    6667mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type)
    6768{
    68   mrb_assert(mrb_type(v) == MRB_TT_DATA);
     69  mrb_assert(mrb_data_p(v));
    6970  DATA_PTR(v) = ptr;
    7071  DATA_TYPE(v) = type;
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/debug.h

    r331 r439  
    1 /*
    2 ** mruby/debug.h - mruby debug info
     1/**
     2** @file mruby/debug.h - mruby debug info
    33**
    44** See Copyright Notice in mruby.h
     
    2727typedef struct mrb_irep_debug_info_file {
    2828  uint32_t start_pos;
    29   const char *filename;
    3029  mrb_sym filename_sym;
    3130  uint32_t line_entry_count;
     
    4847 * @return returns NULL if not found
    4948 */
    50 MRB_API const char *mrb_debug_get_filename(mrb_irep *irep, uint32_t pc);
     49MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc);
    5150
    5251/*
     
    5453 * @return returns -1 if not found
    5554 */
    56 MRB_API int32_t mrb_debug_get_line(mrb_irep *irep, uint32_t pc);
     55MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc);
    5756
     57MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep);
    5858MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file(
    59     mrb_state *mrb, mrb_irep *irep,
     59    mrb_state *mrb, mrb_irep_debug_info *info,
     60    const char *filename, uint16_t *lines,
    6061    uint32_t start_pos, uint32_t end_pos);
    61 MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep);
    6262MRB_API void mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d);
    6363
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/dump.h

    r331 r439  
    1 /*
    2 ** mruby/dump.h - mruby binary dumper (mrbc binary format)
     1/**
     2** @file mruby/dump.h - mruby binary dumper (mrbc binary format)
    33**
    44** See Copyright Notice in mruby.h
     
    3232#endif
    3333MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
     34MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
    3435
    3536/* dump/load error code
     
    5354#define RITE_BINARY_IDENT              "RITE"
    5455#define RITE_BINARY_IDENT_LIL          "ETIR"
    55 #define RITE_BINARY_FORMAT_VER         "0004"
     56#define RITE_BINARY_FORMAT_VER         "0006"
    5657#define RITE_COMPILER_NAME             "MATZ"
    5758#define RITE_COMPILER_VERSION          "0000"
    5859
    59 #define RITE_VM_VER                    "0000"
     60#define RITE_VM_VER                    "0002"
    6061
    6162#define RITE_BINARY_EOF                "END\0"
    6263#define RITE_SECTION_IREP_IDENT        "IREP"
    63 #define RITE_SECTION_LINENO_IDENT      "LINE"
    6464#define RITE_SECTION_DEBUG_IDENT       "DBG\0"
    6565#define RITE_SECTION_LV_IDENT          "LVAR"
     
    6767#define MRB_DUMP_DEFAULT_STR_LEN      128
    6868#define MRB_DUMP_ALIGNMENT            sizeof(uint32_t)
    69 
    70 #ifdef __CA850__
    71 #pragma pack(1)
    72 #elif __RX
    73 #pragma pack
    74 #elif _MSC_VER
    75 #pragma pack(push, 1)
    76 #endif
    77 #ifndef __GNUC__
    78 #define __attribute__(x)
    79 #endif // !__GNUC__
    8069
    8170/* binary header */
     
    8776  uint8_t compiler_name[4];   /* Compiler name */
    8877  uint8_t compiler_version[4];
    89 } __attribute__((packed));
     78};
    9079
    9180/* section header */
     
    9685struct rite_section_header {
    9786  RITE_SECTION_HEADER;
    98 } __attribute__((packed));
     87};
    9988
    10089struct rite_section_irep_header {
     
    10291
    10392  uint8_t rite_version[4];    /* Rite Instruction Specification Version */
    104 } __attribute__((packed));
    105 
    106 struct rite_section_lineno_header {
    107   RITE_SECTION_HEADER;
    108 } __attribute__((packed));
     93};
    10994
    11095struct rite_section_debug_header {
    11196  RITE_SECTION_HEADER;
    112 } __attribute__((packed));
     97};
    11398
    11499struct rite_section_lv_header {
    115100  RITE_SECTION_HEADER;
    116 } __attribute__((packed));
     101};
    117102
    118103#define RITE_LV_NULL_MARK              UINT16_MAX
     
    120105struct rite_binary_footer {
    121106  RITE_SECTION_HEADER;
    122 } __attribute__((packed));
    123 
    124 #ifdef __CA850__
    125 #pragma pack(8)
    126 #elif __RX
    127 #pragma unpack
    128 #elif _MSC_VER
    129 #pragma pack(pop)
    130 #endif
     107};
    131108
    132109static inline int
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/error.h

    r331 r439  
    1 /*
    2 ** mruby/error.h - Exception class
     1/**
     2** @file mruby/error.h - Exception class
    33**
    44** See Copyright Notice in mruby.h
     
    2525MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str);
    2626#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
    27 MRB_API mrb_value mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv);
     27MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
    2828MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
    2929MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb);
    3030MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...);
    3131
    32 /* declaration for fail method */
     32/* declaration for `fail` method */
    3333MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
    3434
     35#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
    3536struct RBreak {
    3637  MRB_OBJECT_HEADER;
    37   struct iv_tbl *iv;
    3838  struct RProc *proc;
    3939  mrb_value val;
    4040};
     41#define mrb_break_value_get(brk) ((brk)->val)
     42#define mrb_break_value_set(brk, v) ((brk)->val = v)
     43#else
     44struct RBreak {
     45  MRB_OBJECT_HEADER;
     46  struct RProc *proc;
     47  union mrb_value_union value;
     48};
     49#define RBREAK_VALUE_TT_MASK ((1 << 8) - 1)
     50static inline mrb_value
     51mrb_break_value_get(struct RBreak *brk)
     52{
     53  mrb_value val;
     54  val.value = brk->value;
     55  val.tt = (enum mrb_vtype)(brk->flags & RBREAK_VALUE_TT_MASK);
     56  return val;
     57}
     58static inline void
     59mrb_break_value_set(struct RBreak *brk, mrb_value val)
     60{
     61  brk->value = val.value;
     62  brk->flags &= ~RBREAK_VALUE_TT_MASK;
     63  brk->flags |= val.tt;
     64}
     65#endif  /* MRB_64BIT || MRB_USE_FLOAT || MRB_NAN_BOXING || MRB_WORD_BOXING */
     66#define mrb_break_proc_get(brk) ((brk)->proc)
     67#define mrb_break_proc_set(brk, p) ((brk)->proc = p)
    4168
    4269/**
    4370 * Protect
    4471 *
    45  * @mrbgem mruby-error
     72 * Implemented in the mruby-error mrbgem
    4673 */
    4774MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state);
     
    5077 * Ensure
    5178 *
    52  * @mrbgem mruby-error
     79 * Implemented in the mruby-error mrbgem
    5380 */
    5481MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
     
    5885 * Rescue
    5986 *
    60  * @mrbgem mruby-error
     87 * Implemented in the mruby-error mrbgem
    6188 */
    6289MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
     
    6693 * Rescue exception
    6794 *
    68  * @mrbgem mruby-error
     95 * Implemented in the mruby-error mrbgem
    6996 */
    7097MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/gc.h

    r331 r439  
    1 /*
    2 ** mruby/gc.h - garbage collector for mruby
     1/**
     2** @file mruby/gc.h - garbage collector for mruby
    33**
    44** See Copyright Notice in mruby.h
     
    3434} mrb_gc_state;
    3535
     36/* Disable MSVC warning "C4200: nonstandard extension used: zero-sized array
     37 * in struct/union" when in C++ mode */
     38#ifdef _MSC_VER
     39#pragma warning(push)
     40#pragma warning(disable : 4200)
     41#endif
     42
    3643typedef struct mrb_heap_page {
    3744  struct RBasic *freelist;
     
    4350  void *objects[];
    4451} mrb_heap_page;
     52
     53#ifdef _MSC_VER
     54#pragma warning(pop)
     55#endif
    4556
    4657typedef struct mrb_gc {
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/hash.h

    r331 r439  
    1 /*
    2 ** mruby/hash.h - Hash class
     1/**
     2** @file mruby/hash.h - Hash class
    33**
    44** See Copyright Notice in mruby.h
     
    99
    1010#include "common.h"
    11 #include <mruby/khash.h>
    1211
    1312/**
     
    1918  MRB_OBJECT_HEADER;
    2019  struct iv_tbl *iv;
    21   struct kh_ht *ht;
     20  struct htable *ht;
    2221};
    2322
     
    2524#define mrb_hash_value(p)  mrb_obj_value((void*)(p))
    2625
    27 MRB_API mrb_value mrb_hash_new_capa(mrb_state*, mrb_int);
     26MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
     27MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
     28MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
    2829
    2930/*
     
    7576 * Equivalent to:
    7677 *
    77  *     hash.hash_key?(key) ? hash[key] : def
     78 *     hash.key?(key) ? hash[key] : def
    7879 *
    7980 * @param mrb The mruby state reference.
     
    9596 * @param hash The target hash.
    9697 * @param key The key to delete.
    97  * @return The deleted value.
     98 * @return The deleted value. This value is not protected from GC. Use `mrb_gc_protect()` if necessary.
    9899 */
    99100MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
     
    111112 */
    112113MRB_API mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash);
    113 MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
     114/*
     115 * Check if the hash has the key.
     116 *
     117 * Equivalent to:
     118 *
     119 *     hash.key?(key)
     120 *
     121 * @param mrb The mruby state reference.
     122 * @param hash The target hash.
     123 * @param key The key to check existence.
     124 * @return True if the hash has the key
     125 */
     126MRB_API mrb_bool mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key);
    114127
    115128/*
     
    124137 * @return True if the hash is empty, false otherwise.
    125138 */
    126 MRB_API mrb_value mrb_hash_empty_p(mrb_state *mrb, mrb_value self);
     139MRB_API mrb_bool mrb_hash_empty_p(mrb_state *mrb, mrb_value self);
    127140
    128141/*
     
    152165MRB_API mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash);
    153166
    154 /* declaration of struct kh_ht */
    155 /* be careful when you touch the internal */
    156 typedef struct {
    157   mrb_value v;
    158   mrb_int n;
    159 } mrb_hash_value;
    160 
    161 KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE)
     167/*
     168 * Get hash size.
     169 *
     170 * Equivalent to:
     171 *
     172 *      hash.size
     173 *
     174 * @param mrb The mruby state reference.
     175 * @param hash The target hash.
     176 * @return The hash size.
     177 */
     178MRB_API mrb_int mrb_hash_size(mrb_state *mrb, mrb_value hash);
     179
     180/*
     181 * Copies the hash.
     182 *
     183 *
     184 * @param mrb The mruby state reference.
     185 * @param hash The target hash.
     186 * @return The copy of the hash
     187 */
     188MRB_API mrb_value mrb_hash_dup(mrb_state *mrb, mrb_value hash);
     189
     190/*
     191 * Merges two hashes. The first hash will be modified by the
     192 * second hash.
     193 *
     194 * @param mrb The mruby state reference.
     195 * @param hash1 The target hash.
     196 * @param hash2 Updating hash
     197 */
     198MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2);
    162199
    163200/* RHASH_TBL allocates st_table if not available. */
     
    166203#define RHASH_IFNONE(h)       mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone"))
    167204#define RHASH_PROCDEFAULT(h)  RHASH_IFNONE(h)
    168 MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);
    169205
    170206#define MRB_HASH_DEFAULT      1
     
    178214void mrb_gc_free_hash(mrb_state*, struct RHash*);
    179215
     216/* return non zero to break the loop */
     217typedef int (mrb_hash_foreach_func)(mrb_state *mrb, mrb_value key, mrb_value val, void *data);
     218MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p);
     219
    180220MRB_END_DECL
    181221
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/irep.h

    r331 r439  
    1 /*
    2 ** mruby/irep.h - mrb_irep structure
     1/**
     2** @file mruby/irep.h - mrb_irep structure
    33**
    44** See Copyright Notice in mruby.h
     
    3333  uint8_t flags;
    3434
    35   mrb_code *iseq;
     35  const mrb_code *iseq;
    3636  mrb_value *pool;
    3737  mrb_sym *syms;
     
    4040  struct mrb_locals *lv;
    4141  /* debug info */
    42   mrb_bool own_filename;
    43   const char *filename;
    44   uint16_t *lines;
    4542  struct mrb_irep_debug_info* debug_info;
    4643
    47   size_t ilen, plen, slen, rlen, refcnt;
     44  uint16_t ilen, plen, slen, rlen;
     45  uint32_t refcnt;
    4846} mrb_irep;
    4947
     
    5149
    5250MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
     51
     52/* @param [const uint8_t*] irep code, expected as a literal */
    5353MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
     54
     55/*
     56 * @param [const void*] irep code
     57 * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
     58 */
     59MRB_API mrb_value mrb_load_irep_buf(mrb_state*, const void*, size_t);
     60
     61/* @param [const uint8_t*] irep code, expected as a literal */
    5462MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*);
     63
     64/*
     65 * @param [const void*] irep code
     66 * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
     67 */
     68MRB_API mrb_value mrb_load_irep_buf_cxt(mrb_state*, const void*, size_t, mrbc_context*);
     69
    5570void mrb_irep_free(mrb_state*, struct mrb_irep*);
    5671void mrb_irep_incref(mrb_state*, struct mrb_irep*);
    5772void mrb_irep_decref(mrb_state*, struct mrb_irep*);
     73void mrb_irep_cutref(mrb_state*, struct mrb_irep*);
     74void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep);
     75
     76struct mrb_insn_data {
     77  uint8_t insn;
     78  uint16_t a;
     79  uint16_t b;
     80  uint8_t c;
     81};
     82
     83struct mrb_insn_data mrb_decode_insn(const mrb_code *pc);
    5884
    5985MRB_END_DECL
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/istruct.h

    r331 r439  
    1 /*
    2 ** mruby/istruct.h - Inline structures
     1/**
     2** @file mruby/istruct.h - Inline structures
    33**
    44** See Copyright Notice in mruby.h
     
    2020#define ISTRUCT_DATA_SIZE (sizeof(void*) * 3)
    2121
    22 struct RIstruct {
     22struct RIStruct {
    2323  MRB_OBJECT_HEADER;
    2424  char inline_data[ISTRUCT_DATA_SIZE];
    2525};
    2626
    27 #define RISTRUCT(obj)         ((struct RIstruct*)(mrb_ptr(obj)))
     27#define RISTRUCT(obj)         ((struct RIStruct*)(mrb_ptr(obj)))
    2828#define ISTRUCT_PTR(obj)      (RISTRUCT(obj)->inline_data)
    2929
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/khash.h

    r331 r439  
    1 /*
    2 ** mruby/khash.c - Hash for mruby
     1/**
     2** @file mruby/khash.h - Hash for mruby
    33**
    44** See Copyright Notice in mruby.h
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/numeric.h

    r331 r439  
    1 /*
    2 ** mruby/numeric.h - Numeric, Integer, Float, Fixnum class
     1/**
     2** @file mruby/numeric.h - Numeric, Integer, Float, Fixnum class
    33**
    44** See Copyright Notice in mruby.h
     
    1717MRB_BEGIN_DECL
    1818
    19 #define POSFIXABLE(f) ((f) <= MRB_INT_MAX)
    20 #define NEGFIXABLE(f) ((f) >= MRB_INT_MIN)
    21 #define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
    22 
     19#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_INT_MAX)
     20#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_INT_MIN)
     21#define TYPED_FIXABLE(f,t) (TYPED_POSFIXABLE(f,t) && TYPED_NEGFIXABLE(f,t))
     22#define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int)
     23#define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int)
     24#define FIXABLE(f) TYPED_FIXABLE(f,mrb_int)
     25#ifndef MRB_WITHOUT_FLOAT
    2326#ifdef MRB_INT64
    24 #define FIXABLE_FLOAT(f) FIXABLE((mrb_int)(f))
     27#define FIXABLE_FLOAT(f) ((f)>=-9223372036854775808.0 && (f)<9223372036854775808.0)
    2528#else
    26 #define FIXABLE_FLOAT(f) FIXABLE(f)
     29#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,mrb_float)
     30#endif
    2731#endif
    2832
     33#ifndef MRB_WITHOUT_FLOAT
    2934MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
    30 MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base);
     35#endif
     36MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
    3137/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
     38#ifndef MRB_WITHOUT_FLOAT
    3239MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
    3340MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
     41MRB_API mrb_value mrb_int_value(mrb_state *mrb, mrb_float f);
     42#endif
    3443
    35 mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y);
    36 mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y);
    37 mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y);
    38 mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y);
     44MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y);
     45MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y);
     46MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y);
    3947
    4048#ifndef __has_builtin
     
    153161#endif
    154162
     163#ifndef MRB_WITHOUT_FLOAT
     164# include <stdint.h>
     165# include <float.h>
     166
     167# define MRB_FLT_RADIX          FLT_RADIX
     168
     169# ifdef MRB_USE_FLOAT
     170#  define MRB_FLT_MANT_DIG      FLT_MANT_DIG
     171#  define MRB_FLT_EPSILON       FLT_EPSILON
     172#  define MRB_FLT_DIG           FLT_DIG
     173#  define MRB_FLT_MIN_EXP       FLT_MIN_EXP
     174#  define MRB_FLT_MIN           FLT_MIN
     175#  define MRB_FLT_MIN_10_EXP    FLT_MIN_10_EXP
     176#  define MRB_FLT_MAX_EXP       FLT_MAX_EXP
     177#  define MRB_FLT_MAX           FLT_MAX
     178#  define MRB_FLT_MAX_10_EXP    FLT_MAX_10_EXP
     179
     180# else /* not MRB_USE_FLOAT */
     181#  define MRB_FLT_MANT_DIG      DBL_MANT_DIG
     182#  define MRB_FLT_EPSILON       DBL_EPSILON
     183#  define MRB_FLT_DIG           DBL_DIG
     184#  define MRB_FLT_MIN_EXP       DBL_MIN_EXP
     185#  define MRB_FLT_MIN           DBL_MIN
     186#  define MRB_FLT_MIN_10_EXP    DBL_MIN_10_EXP
     187#  define MRB_FLT_MAX_EXP       DBL_MAX_EXP
     188#  define MRB_FLT_MAX           DBL_MAX
     189#  define MRB_FLT_MAX_10_EXP    DBL_MAX_10_EXP
     190# endif /* MRB_USE_FLOAT */
     191#endif /* MRB_WITHOUT_FLOAT */
     192
    155193MRB_END_DECL
    156194
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/object.h

    r331 r439  
    1 /*
    2 ** mruby/object.h - mruby object definition
     1/**
     2** @file mruby/object.h - mruby object definition
    33**
    44** See Copyright Notice in mruby.h
     
    99
    1010#define MRB_OBJECT_HEADER \
    11   enum mrb_vtype tt:8;\
    12   uint32_t color:3;\
    13   uint32_t flags:21;\
    14   struct RClass *c;\
    15   struct RBasic *gcnext
     11  struct RClass *c;       \
     12  struct RBasic *gcnext;  \
     13  enum mrb_vtype tt:8;    \
     14  uint32_t color:3;       \
     15  uint32_t flags:21
    1616
    17 #define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag)
    18 
     17#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & (flag))
    1918
    2019struct RBasic {
     
    2322#define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v)))
    2423
    25 #define MRB_FROZEN_P(o) ((o)->flags & MRB_FLAG_IS_FROZEN)
    26 #define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FLAG_IS_FROZEN)
    27 #define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FLAG_IS_FROZEN)
     24#define MRB_FL_OBJ_IS_FROZEN (1 << 20)
     25#define MRB_FROZEN_P(o) ((o)->flags & MRB_FL_OBJ_IS_FROZEN)
     26#define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FL_OBJ_IS_FROZEN)
     27#define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FL_OBJ_IS_FROZEN)
     28#define mrb_frozen_p(o) MRB_FROZEN_P(o)
    2829
    2930struct RObject {
     
    3334#define mrb_obj_ptr(v)   ((struct RObject*)(mrb_ptr(v)))
    3435
    35 #define mrb_immediate_p(x) (mrb_type(x) < MRB_TT_HAS_BASIC)
    3636#define mrb_special_const_p(x) mrb_immediate_p(x)
    3737
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/opcode.h

    r331 r439  
    1 /*
    2 ** mruby/opcode.h - RiteVM operation codes
     1/**
     2** @file mruby/opcode.h - RiteVM operation codes
    33**
    44** See Copyright Notice in mruby.h
     
    88#define MRUBY_OPCODE_H
    99
    10 #define MAXARG_Bx        (0xffff)
    11 #define MAXARG_sBx       (MAXARG_Bx>>1)         /* 'sBx' is signed */
    12 
    13 /* instructions: packed 32 bit      */
    14 /* -------------------------------  */
    15 /*     A:B:C:OP = 9: 9: 7: 7        */
    16 /*      A:Bx:OP =    9:16: 7        */
    17 /*        Ax:OP =      25: 7        */
    18 /*   A:Bz:Cz:OP = 9:14: 2: 7        */
    19 
    20 #define GET_OPCODE(i)            ((int)(((mrb_code)(i)) & 0x7f))
    21 #define GETARG_A(i)              ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
    22 #define GETARG_B(i)              ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
    23 #define GETARG_C(i)              ((int)((((mrb_code)(i)) >>  7) & 0x7f))
    24 #define GETARG_Bx(i)             ((int)((((mrb_code)(i)) >>  7) & 0xffff))
    25 #define GETARG_sBx(i)            ((int)(GETARG_Bx(i)-MAXARG_sBx))
    26 #define GETARG_Ax(i)             ((int32_t)((((mrb_code)(i)) >>  7) & 0x1ffffff))
    27 #define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1))))
    28 #define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1))))
    29 #define GETARG_b(i)              GETARG_UNPACK_b(i,14,2)
    30 #define GETARG_c(i)              GETARG_UNPACK_c(i,14,2)
    31 
    32 #define MKOPCODE(op)          ((op) & 0x7f)
    33 #define MKARG_A(c)            ((mrb_code)((c) & 0x1ff) << 23)
    34 #define MKARG_B(c)            ((mrb_code)((c) & 0x1ff) << 14)
    35 #define MKARG_C(c)            (((c) & 0x7f) <<  7)
    36 #define MKARG_Bx(v)           ((mrb_code)((v) & 0xffff) << 7)
    37 #define MKARG_sBx(v)          MKARG_Bx((v)+MAXARG_sBx)
    38 #define MKARG_Ax(v)           ((mrb_code)((v) & 0x1ffffff) << 7)
    39 #define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
    40 #define MKARG_bc(b,c)         MKARG_PACK(b,14,c,2)
    41 
    42 #define MKOP_A(op,a)        (MKOPCODE(op)|MKARG_A(a))
    43 #define MKOP_AB(op,a,b)     (MKOP_A(op,a)|MKARG_B(b))
    44 #define MKOP_ABC(op,a,b,c)  (MKOP_AB(op,a,b)|MKARG_C(c))
    45 #define MKOP_ABx(op,a,bx)   (MKOP_A(op,a)|MKARG_Bx(bx))
    46 #define MKOP_Bx(op,bx)      (MKOPCODE(op)|MKARG_Bx(bx))
    47 #define MKOP_sBx(op,sbx)    (MKOPCODE(op)|MKARG_sBx(sbx))
    48 #define MKOP_AsBx(op,a,sbx) (MKOP_A(op,a)|MKARG_sBx(sbx))
    49 #define MKOP_Ax(op,ax)      (MKOPCODE(op)|MKARG_Ax(ax))
    50 #define MKOP_Abc(op,a,b,c)  (MKOP_A(op,a)|MKARG_bc(b,c))
    51 
    52 enum {
    53   /*-----------------------------------------------------------------------
    54   operation code  operand description
    55   ------------------------------------------------------------------------*/
    56   OP_NOP=0,/*                                                             */
    57   OP_MOVE,/*      A B     R(A) := R(B)                                    */
    58   OP_LOADL,/*     A Bx    R(A) := Pool(Bx)                                */
    59   OP_LOADI,/*     A sBx   R(A) := sBx                                     */
    60   OP_LOADSYM,/*   A Bx    R(A) := Syms(Bx)                                */
    61   OP_LOADNIL,/*   A       R(A) := nil                                     */
    62   OP_LOADSELF,/*  A       R(A) := self                                    */
    63   OP_LOADT,/*     A       R(A) := true                                    */
    64   OP_LOADF,/*     A       R(A) := false                                   */
    65 
    66   OP_GETGLOBAL,/* A Bx    R(A) := getglobal(Syms(Bx))                     */
    67   OP_SETGLOBAL,/* A Bx    setglobal(Syms(Bx), R(A))                       */
    68   OP_GETSPECIAL,/*A Bx    R(A) := Special[Bx]                             */
    69   OP_SETSPECIAL,/*A Bx    Special[Bx] := R(A)                             */
    70   OP_GETIV,/*     A Bx    R(A) := ivget(Syms(Bx))                         */
    71   OP_SETIV,/*     A Bx    ivset(Syms(Bx),R(A))                            */
    72   OP_GETCV,/*     A Bx    R(A) := cvget(Syms(Bx))                         */
    73   OP_SETCV,/*     A Bx    cvset(Syms(Bx),R(A))                            */
    74   OP_GETCONST,/*  A Bx    R(A) := constget(Syms(Bx))                      */
    75   OP_SETCONST,/*  A Bx    constset(Syms(Bx),R(A))                         */
    76   OP_GETMCNST,/*  A Bx    R(A) := R(A)::Syms(Bx)                          */
    77   OP_SETMCNST,/*  A Bx    R(A+1)::Syms(Bx) := R(A)                        */
    78   OP_GETUPVAR,/*  A B C   R(A) := uvget(B,C)                              */
    79   OP_SETUPVAR,/*  A B C   uvset(B,C,R(A))                                 */
    80 
    81   OP_JMP,/*       sBx     pc+=sBx                                         */
    82   OP_JMPIF,/*     A sBx   if R(A) pc+=sBx                                 */
    83   OP_JMPNOT,/*    A sBx   if !R(A) pc+=sBx                                */
    84   OP_ONERR,/*     sBx     rescue_push(pc+sBx)                             */
    85   OP_RESCUE,/*    A B C   if A (if C exc=R(A) else R(A) := exc);
    86                           if B R(B) := exc.isa?(R(B)); clear(exc)         */
    87   OP_POPERR,/*    A       A.times{rescue_pop()}                           */
    88   OP_RAISE,/*     A       raise(R(A))                                     */
    89   OP_EPUSH,/*     Bx      ensure_push(SEQ[Bx])                            */
    90   OP_EPOP,/*      A       A.times{ensure_pop().call}                      */
    91 
    92   OP_SEND,/*      A B C   R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C))    */
    93   OP_SENDB,/*     A B C   R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/
    94   OP_FSEND,/*     A B C   R(A) := fcall(R(A),Syms(B),R(A+1),...,R(A+C-1)) */
    95   OP_CALL,/*      A       R(A) := self.call(frame.argc, frame.argv)       */
    96   OP_SUPER,/*     A C     R(A) := super(R(A+1),... ,R(A+C+1))             */
    97   OP_ARGARY,/*    A Bx    R(A) := argument array (16=6:1:5:4)             */
    98   OP_ENTER,/*     Ax      arg setup according to flags (23=5:5:1:5:5:1:1) */
    99   OP_KARG,/*      A B C   R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B))  */
    100   OP_KDICT,/*     A C     R(A) := kdict                                   */
    101 
    102   OP_RETURN,/*    A B     return R(A) (B=normal,in-block return/break)    */
    103   OP_TAILCALL,/*  A B C   return call(R(A),Syms(B),*R(C))                 */
    104   OP_BLKPUSH,/*   A Bx    R(A) := block (16=6:1:5:4)                      */
    105 
    106   OP_ADD,/*       A B C   R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)            */
    107   OP_ADDI,/*      A B C   R(A) := R(A)+C (Syms[B]=:+)                     */
    108   OP_SUB,/*       A B C   R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)            */
    109   OP_SUBI,/*      A B C   R(A) := R(A)-C (Syms[B]=:-)                     */
    110   OP_MUL,/*       A B C   R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)            */
    111   OP_DIV,/*       A B C   R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)            */
    112   OP_EQ,/*        A B C   R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)          */
    113   OP_LT,/*        A B C   R(A) := R(A)<R(A+1)  (Syms[B]=:<,C=1)           */
    114   OP_LE,/*        A B C   R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)          */
    115   OP_GT,/*        A B C   R(A) := R(A)>R(A+1)  (Syms[B]=:>,C=1)           */
    116   OP_GE,/*        A B C   R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)          */
    117 
    118   OP_ARRAY,/*     A B C   R(A) := ary_new(R(B),R(B+1)..R(B+C))            */
    119   OP_ARYCAT,/*    A B     ary_cat(R(A),R(B))                              */
    120   OP_ARYPUSH,/*   A B     ary_push(R(A),R(B))                             */
    121   OP_AREF,/*      A B C   R(A) := R(B)[C]                                 */
    122   OP_ASET,/*      A B C   R(B)[C] := R(A)                                 */
    123   OP_APOST,/*     A B C   *R(A),R(A+1)..R(A+C) := R(A)                    */
    124 
    125   OP_STRING,/*    A Bx    R(A) := str_dup(Lit(Bx))                        */
    126   OP_STRCAT,/*    A B     str_cat(R(A),R(B))                              */
    127 
    128   OP_HASH,/*      A B C   R(A) := hash_new(R(B),R(B+1)..R(B+C))           */
    129   OP_LAMBDA,/*    A Bz Cz R(A) := lambda(SEQ[Bz],Cz)                      */
    130   OP_RANGE,/*     A B C   R(A) := range_new(R(B),R(B+1),C)                */
    131 
    132   OP_OCLASS,/*    A       R(A) := ::Object                                */
    133   OP_CLASS,/*     A B     R(A) := newclass(R(A),Syms(B),R(A+1))           */
    134   OP_MODULE,/*    A B     R(A) := newmodule(R(A),Syms(B))                 */
    135   OP_EXEC,/*      A Bx    R(A) := blockexec(R(A),SEQ[Bx])                 */
    136   OP_METHOD,/*    A B     R(A).newmethod(Syms(B),R(A+1))                  */
    137   OP_SCLASS,/*    A B     R(A) := R(B).singleton_class                    */
    138   OP_TCLASS,/*    A       R(A) := target_class                            */
    139 
    140   OP_DEBUG,/*     A B C   print R(A),R(B),R(C)                            */
    141   OP_STOP,/*              stop VM                                         */
    142   OP_ERR,/*       Bx      raise RuntimeError with message Lit(Bx)         */
    143 
    144   OP_RSVD1,/*             reserved instruction #1                         */
    145   OP_RSVD2,/*             reserved instruction #2                         */
    146   OP_RSVD3,/*             reserved instruction #3                         */
    147   OP_RSVD4,/*             reserved instruction #4                         */
    148   OP_RSVD5,/*             reserved instruction #5                         */
     10enum mrb_insn {
     11#define OPCODE(x,_) OP_ ## x,
     12#include "mruby/ops.h"
     13#undef OPCODE
    14914};
    15015
     
    15924#define OP_R_RETURN 2
    16025
     26#define PEEK_B(pc) (*(pc))
     27#define PEEK_S(pc) ((pc)[0]<<8|(pc)[1])
     28#define PEEK_W(pc) ((pc)[0]<<16|(pc)[1]<<8|(pc)[2])
     29
     30#define READ_B() PEEK_B(pc++)
     31#define READ_S() (pc+=2, PEEK_S(pc-2))
     32#define READ_W() (pc+=3, PEEK_W(pc-3))
     33
     34#define FETCH_Z() /* nothing */
     35#define FETCH_B() do {a=READ_B();} while (0)
     36#define FETCH_BB() do {a=READ_B(); b=READ_B();} while (0)
     37#define FETCH_BBB() do {a=READ_B(); b=READ_B(); c=READ_B();} while (0)
     38#define FETCH_BS() do {a=READ_B(); b=READ_S();} while (0)
     39#define FETCH_S() do {a=READ_S();} while (0)
     40#define FETCH_W() do {a=READ_W();} while (0)
     41
     42/* with OP_EXT1 (1st 16bit) */
     43#define FETCH_Z_1() FETCH_Z()
     44#define FETCH_B_1() FETCH_S()
     45#define FETCH_BB_1() do {a=READ_S(); b=READ_B();} while (0)
     46#define FETCH_BBB_1() do {a=READ_S(); b=READ_B(); c=READ_B();} while (0)
     47#define FETCH_BS_1() do {a=READ_S(); b=READ_S();} while (0)
     48#define FETCH_S_1() FETCH_S()
     49#define FETCH_W_1() FETCH_W()
     50
     51/* with OP_EXT2 (2nd 16bit) */
     52#define FETCH_Z_2() FETCH_Z()
     53#define FETCH_B_2() FETCH_B()
     54#define FETCH_BB_2() do {a=READ_B(); b=READ_S();} while (0)
     55#define FETCH_BBB_2() do {a=READ_B(); b=READ_S(); c=READ_B();} while (0)
     56#define FETCH_BS_2() FETCH_BS()
     57#define FETCH_S_2() FETCH_S()
     58#define FETCH_W_2() FETCH_W()
     59
     60/* with OP_EXT3 (1st & 2nd 16bit) */
     61#define FETCH_Z_3() FETCH_Z()
     62#define FETCH_B_3() FETCH_B()
     63#define FETCH_BB_3() do {a=READ_S(); b=READ_S();} while (0)
     64#define FETCH_BBB_3() do {a=READ_S(); b=READ_S(); c=READ_B();} while (0)
     65#define FETCH_BS_3() do {a=READ_S(); b=READ_S();} while (0)
     66#define FETCH_S_3() FETCH_S()
     67#define FETCH_W_3() FETCH_W()
     68
    16169#endif  /* MRUBY_OPCODE_H */
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/proc.h

    r331 r439  
    1 /*
    2 ** mruby/proc.h - Proc class
     1/**
     2** @file mruby/proc.h - Proc class
    33**
    44** See Copyright Notice in mruby.h
     
    1919  MRB_OBJECT_HEADER;
    2020  mrb_value *stack;
    21   ptrdiff_t cioff;
    22   union {
    23     mrb_sym mid;
    24     struct mrb_context *c;
    25   } cxt;
     21  struct mrb_context *cxt;
     22  mrb_sym mid;
    2623};
    2724
    28 #define MRB_SET_ENV_STACK_LEN(e,len) (e)->flags = (unsigned int)(len)
    29 #define MRB_ENV_STACK_LEN(e) ((mrb_int)(e)->flags)
    30 #define MRB_ENV_UNSHARE_STACK(e) ((e)->cioff = -1)
    31 #define MRB_ENV_STACK_SHARED_P(e) ((e)->cioff >= 0)
     25/* flags (21bits): 1(shared flag):10(cioff/bidx):10(stack_len) */
     26#define MRB_ENV_SET_STACK_LEN(e,len) ((e)->flags = (((e)->flags & ~0x3ff)|((unsigned int)(len) & 0x3ff)))
     27#define MRB_ENV_STACK_LEN(e) ((mrb_int)((e)->flags & 0x3ff))
     28#define MRB_ENV_STACK_UNSHARED (1<<20)
     29#define MRB_ENV_UNSHARE_STACK(e) ((e)->flags |= MRB_ENV_STACK_UNSHARED)
     30#define MRB_ENV_STACK_SHARED_P(e) (((e)->flags & MRB_ENV_STACK_UNSHARED) == 0)
     31#define MRB_ENV_BIDX(e) (((e)->flags >> 10) & 0x3ff)
     32#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10))
    3233
    33 MRB_API void mrb_env_unshare(mrb_state*, struct REnv*);
     34void mrb_env_unshare(mrb_state*, struct REnv*);
    3435
    3536struct RProc {
     
    3940    mrb_func_t func;
    4041  } body;
    41   struct RClass *target_class;
    42   struct REnv *env;
     42  struct RProc *upper;
     43  union {
     44    struct RClass *target_class;
     45    struct REnv *env;
     46  } e;
    4347};
    4448
     
    5256#define MRB_ASPEC_BLOCK(a)        ((a) & 1)
    5357
    54 #define MRB_PROC_CFUNC 128
    55 #define MRB_PROC_CFUNC_P(p) (((p)->flags & MRB_PROC_CFUNC) != 0)
     58#define MRB_PROC_CFUNC_FL 128
     59#define MRB_PROC_CFUNC_P(p) (((p)->flags & MRB_PROC_CFUNC_FL) != 0)
     60#define MRB_PROC_CFUNC(p) (p)->body.func
    5661#define MRB_PROC_STRICT 256
    5762#define MRB_PROC_STRICT_P(p) (((p)->flags & MRB_PROC_STRICT) != 0)
    5863#define MRB_PROC_ORPHAN 512
    5964#define MRB_PROC_ORPHAN_P(p) (((p)->flags & MRB_PROC_ORPHAN) != 0)
     65#define MRB_PROC_ENVSET 1024
     66#define MRB_PROC_ENV_P(p) (((p)->flags & MRB_PROC_ENVSET) != 0)
     67#define MRB_PROC_ENV(p) (MRB_PROC_ENV_P(p) ? (p)->e.env : NULL)
     68#define MRB_PROC_TARGET_CLASS(p) (MRB_PROC_ENV_P(p) ? (p)->e.env->c : (p)->e.target_class)
     69#define MRB_PROC_SET_TARGET_CLASS(p,tc) do {\
     70  if (MRB_PROC_ENV_P(p)) {\
     71    (p)->e.env->c = (tc);\
     72    mrb_field_write_barrier(mrb, (struct RBasic*)(p)->e.env, (struct RBasic*)(tc));\
     73  }\
     74  else {\
     75    (p)->e.target_class = (tc);\
     76    mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)(tc));\
     77  }\
     78} while (0)
     79#define MRB_PROC_SCOPE 2048
     80#define MRB_PROC_SCOPE_P(p) (((p)->flags & MRB_PROC_SCOPE) != 0)
    6081
    6182#define mrb_proc_ptr(v)    ((struct RProc*)(mrb_ptr(v)))
     
    6687MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
    6788void mrb_proc_copy(struct RProc *a, struct RProc *b);
     89mrb_int mrb_proc_arity(const struct RProc *p);
    6890
    6991/* implementation of #send method */
    70 MRB_API mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
     92mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
    7193
    7294/* following functions are defined in mruby-proc-ext so please include it when using */
    73 MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state*, mrb_func_t, mrb_int, const mrb_value*);
    74 MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int);
     95MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv);
     96MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
    7597/* old name */
    7698#define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx)
    7799
     100#define MRB_METHOD_FUNC_FL 1
     101#define MRB_METHOD_NOARG_FL 2
     102#ifndef MRB_METHOD_T_STRUCT
     103
     104#define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL)
     105#define MRB_METHOD_NOARG_P(m) (((uintptr_t)(m))&MRB_METHOD_NOARG_FL)
     106#define MRB_METHOD_NOARG_SET(m) ((m)=(mrb_method_t)(((uintptr_t)(m))|MRB_METHOD_NOARG_FL))
     107#define MRB_METHOD_FUNC(m) ((mrb_func_t)((uintptr_t)(m)&(~(MRB_METHOD_NOARG_FL|MRB_METHOD_FUNC_FL))))
     108#define MRB_METHOD_FROM_FUNC(m,fn) ((m)=(mrb_method_t)((((uintptr_t)(fn))|MRB_METHOD_FUNC_FL)))
     109#define MRB_METHOD_FROM_PROC(m,pr) ((m)=(mrb_method_t)(pr))
     110#define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
     111#define MRB_METHOD_PROC(m) ((struct RProc*)(m))
     112#define MRB_METHOD_UNDEF_P(m) ((m)==0)
     113
     114#else
     115
     116#define MRB_METHOD_FUNC_P(m) ((m).flags&MRB_METHOD_FUNC_FL)
     117#define MRB_METHOD_NOARG_P(m) ((m).flags&MRB_METHOD_NOARG_FL)
     118#define MRB_METHOD_FUNC(m) ((m).func)
     119#define MRB_METHOD_NOARG_SET(m) do{(m).flags|=MRB_METHOD_NOARG_FL;}while(0)
     120#define MRB_METHOD_FROM_FUNC(m,fn) do{(m).flags=MRB_METHOD_FUNC_FL;(m).func=(fn);}while(0)
     121#define MRB_METHOD_FROM_PROC(m,pr) do{(m).flags=0;(m).proc=(pr);}while(0)
     122#define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
     123#define MRB_METHOD_PROC(m) ((m).proc)
     124#define MRB_METHOD_UNDEF_P(m) ((m).proc==NULL)
     125
     126#endif /* MRB_METHOD_T_STRUCT */
     127
     128#define MRB_METHOD_CFUNC_P(m) (MRB_METHOD_FUNC_P(m)?TRUE:(MRB_METHOD_PROC(m)?(MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m))):FALSE))
     129#define MRB_METHOD_CFUNC(m) (MRB_METHOD_FUNC_P(m)?MRB_METHOD_FUNC(m):((MRB_METHOD_PROC(m)&&MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m)))?MRB_PROC_CFUNC(MRB_METHOD_PROC(m)):NULL))
     130
     131
    78132#include <mruby/khash.h>
    79 KHASH_DECLARE(mt, mrb_sym, struct RProc*, TRUE)
     133KHASH_DECLARE(mt, mrb_sym, mrb_method_t, TRUE)
    80134
    81135MRB_END_DECL
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/range.h

    r331 r439  
    1 /*
    2 ** mruby/range.h - Range class
     1/**
     2** @file mruby/range.h - Range class
    33**
    44** See Copyright Notice in mruby.h
     
    1515MRB_BEGIN_DECL
    1616
     17#if defined(MRB_NAN_BOXING) && defined(MRB_64BIT) || defined(MRB_WORD_BOXING)
     18# define MRB_RANGE_EMBED
     19#endif
     20
     21#ifdef MRB_RANGE_EMBED
     22struct RRange {
     23  MRB_OBJECT_HEADER;
     24  mrb_value beg;
     25  mrb_value end;
     26  mrb_bool excl;
     27};
     28# define mrb_gc_free_range(mrb, p) ((void)0)
     29# define RANGE_BEG(p) ((p)->beg)
     30# define RANGE_END(p) ((p)->end)
     31#else
    1732typedef struct mrb_range_edges {
    1833  mrb_value beg;
    1934  mrb_value end;
    2035} mrb_range_edges;
    21 
    2236struct RRange {
    2337  MRB_OBJECT_HEADER;
    2438  mrb_range_edges *edges;
    25   mrb_bool excl : 1;
     39  mrb_bool excl;
    2640};
     41# define mrb_gc_free_range(mrb, p) mrb_free(mrb, (p)->edges)
     42# define RANGE_BEG(p) ((p)->edges->beg)
     43# define RANGE_END(p) ((p)->edges->end)
     44#endif
    2745
    28 MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v);
    29 #define mrb_range_raw_ptr(v) ((struct RRange*)mrb_ptr(v))
    30 #define mrb_range_value(p)  mrb_obj_value((void*)(p))
     46#define mrb_range_beg(mrb, r) RANGE_BEG(mrb_range_ptr(mrb, r))
     47#define mrb_range_end(mrb, r) RANGE_END(mrb_range_ptr(mrb, r))
     48#define mrb_range_excl_p(mrb, r) RANGE_EXCL(mrb_range_ptr(mrb, r))
     49#define mrb_range_raw_ptr(r) ((struct RRange*)mrb_ptr(r))
     50#define mrb_range_value(p) mrb_obj_value((void*)(p))
     51#define RANGE_EXCL(p) ((p)->excl)
     52
     53MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value range);
    3154
    3255/*
     
    4265MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude);
    4366
    44 MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
     67enum mrb_range_beg_len {
     68  MRB_RANGE_TYPE_MISMATCH = 0,  /* (failure) not range */
     69  MRB_RANGE_OK = 1,             /* (success) range */
     70  MRB_RANGE_OUT = 2             /* (failure) out of range */
     71};
     72
     73MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
    4574mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
     75void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r);
    4676
    4777MRB_END_DECL
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/re.h

    r331 r439  
    1 /*
    2 ** mruby/re.h - Regexp class
     1/**
     2** @file mruby/re.h - Regexp class
    33**
    44** See Copyright Notice in mruby.h
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/string.h

    r331 r439  
    1 /*
    2 ** mruby/string.h - String class
     1/**
     2** @file mruby/string.h - String class
    33**
    44** See Copyright Notice in mruby.h
     
    1717extern const char mrb_digitmap[];
    1818
    19 #define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1))
     19#define RSTRING_EMBED_LEN_MAX \
     20  ((mrb_int)(sizeof(void*) * 3 + sizeof(void*) - 32 / CHAR_BIT - 1))
    2021
    2122struct RString {
     
    2324  union {
    2425    struct {
    25       mrb_int len;
     26      mrb_ssize len;
    2627      union {
    27         mrb_int capa;
     28        mrb_ssize capa;
    2829        struct mrb_shared_string *shared;
     30        struct RString *fshared;
    2931      } aux;
    3032      char *ptr;
    3133    } heap;
    32     char ary[RSTRING_EMBED_LEN_MAX + 1];
    3334  } as;
    3435};
     36struct RStringEmbed {
     37  MRB_OBJECT_HEADER;
     38  char ary[];
     39};
     40
     41#define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type)
     42#define RSTR_UNSET_TYPE_FLAG(s) ((s)->flags &= ~(MRB_STR_TYPE_MASK|MRB_STR_EMBED_LEN_MASK))
    3543
    3644#define RSTR_EMBED_P(s) ((s)->flags & MRB_STR_EMBED)
     
    3947#define RSTR_SET_EMBED_LEN(s, n) do {\
    4048  size_t tmp_n = (n);\
    41   s->flags &= ~MRB_STR_EMBED_LEN_MASK;\
    42   s->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\
     49  (s)->flags &= ~MRB_STR_EMBED_LEN_MASK;\
     50  (s)->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\
    4351} while (0)
    4452#define RSTR_SET_LEN(s, n) do {\
     
    4755  }\
    4856  else {\
    49     s->as.heap.len = (mrb_int)(n);\
     57    (s)->as.heap.len = (mrb_ssize)(n);\
    5058  }\
    5159} while (0)
     60#define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary)
    5261#define RSTR_EMBED_LEN(s)\
    5362  (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
    54 #define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr)
     63#define RSTR_EMBEDDABLE_P(len) ((len) <= RSTRING_EMBED_LEN_MAX)
     64
     65#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_PTR(s) : (s)->as.heap.ptr)
    5566#define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len)
    5667#define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa)
     
    6071#define RSTR_UNSET_SHARED_FLAG(s) ((s)->flags &= ~MRB_STR_SHARED)
    6172
     73#define RSTR_FSHARED_P(s) ((s)->flags & MRB_STR_FSHARED)
     74#define RSTR_SET_FSHARED_FLAG(s) ((s)->flags |= MRB_STR_FSHARED)
     75#define RSTR_UNSET_FSHARED_FLAG(s) ((s)->flags &= ~MRB_STR_FSHARED)
     76
    6277#define RSTR_NOFREE_P(s) ((s)->flags & MRB_STR_NOFREE)
    6378#define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE)
    6479#define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE)
    6580
    66 /*
     81#ifdef MRB_UTF8_STRING
     82# define RSTR_ASCII_P(s) ((s)->flags & MRB_STR_ASCII)
     83# define RSTR_SET_ASCII_FLAG(s) ((s)->flags |= MRB_STR_ASCII)
     84# define RSTR_UNSET_ASCII_FLAG(s) ((s)->flags &= ~MRB_STR_ASCII)
     85# define RSTR_WRITE_ASCII_FLAG(s, v) (RSTR_UNSET_ASCII_FLAG(s), (s)->flags |= v)
     86# define RSTR_COPY_ASCII_FLAG(dst, src) RSTR_WRITE_ASCII_FLAG(dst, RSTR_ASCII_P(src))
     87#else
     88# define RSTR_ASCII_P(s) (void)0
     89# define RSTR_SET_ASCII_FLAG(s) (void)0
     90# define RSTR_UNSET_ASCII_FLAG(s) (void)0
     91# define RSTR_WRITE_ASCII_FLAG(s, v) (void)0
     92# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0
     93#endif
     94
     95#define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL)
     96#define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL)
     97
     98/**
    6799 * Returns a pointer from a Ruby string
    68100 */
     
    75107#define RSTRING_END(s)       (RSTRING_PTR(s) + RSTRING_LEN(s))
    76108MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
     109#define RSTRING_CSTR(mrb,s)  mrb_string_cstr(mrb, s)
    77110
    78111#define MRB_STR_SHARED    1
    79 #define MRB_STR_NOFREE    2
    80 #define MRB_STR_NO_UTF    8
    81 #define MRB_STR_EMBED    16
    82 #define MRB_STR_EMBED_LEN_MASK 0x3e0
    83 #define MRB_STR_EMBED_LEN_SHIFT 5
     112#define MRB_STR_FSHARED   2
     113#define MRB_STR_NOFREE    4
     114#define MRB_STR_EMBED     8  /* type flags up to here */
     115#define MRB_STR_POOL     16  /* status flags from here */
     116#define MRB_STR_ASCII    32
     117#define MRB_STR_EMBED_LEN_SHIFT 6
     118#define MRB_STR_EMBED_LEN_BIT 5
     119#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
     120#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1)
     121
    84122
    85123void mrb_gc_free_str(mrb_state*, struct RString*);
    86 MRB_API void mrb_str_modify(mrb_state*, struct RString*);
    87 /*
    88  * Appends self to other. Returns self as a concatnated string.
    89  *
    90  *
    91  *  Example:
    92  *
    93  *     !!!c
     124
     125MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s);
     126/* mrb_str_modify() with keeping ASCII flag if set */
     127MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s);
     128
     129/**
     130 * Finds the index of a substring in a string
     131 */
     132MRB_API mrb_int mrb_str_index(mrb_state *mrb, mrb_value str, const char *p, mrb_int len, mrb_int offset);
     133#define mrb_str_index_lit(mrb, str, lit, off) mrb_str_index(mrb, str, lit, mrb_strlen_lit(lit), off);
     134
     135/**
     136 * Appends self to other. Returns self as a concatenated string.
     137 *
     138 *
     139 * Example:
     140 *
    94141 *     int
    95142 *     main(int argc,
     
    110157 *       str2 = mrb_str_new_lit(mrb, "def");
    111158 *
    112  *       // Concatnates str2 to str1.
     159 *       // Concatenates str2 to str1.
    113160 *       mrb_str_concat(mrb, str1, str2);
    114161 *
    115  *      // Prints new Concatnated Ruby string.
    116  *      mrb_p(mrb, str1);
    117  *
    118  *      mrb_close(mrb);
    119  *      return 0;
    120  *    }
    121  *
    122  *
    123  *  Result:
     162 *       // Prints new Concatenated Ruby string.
     163 *       mrb_p(mrb, str1);
     164 *
     165 *       mrb_close(mrb);
     166 *       return 0;
     167 *     }
     168 *
     169 * Result:
    124170 *
    125171 *     => "abcdef"
    126172 *
    127  * @param [mrb_state] mrb The current mruby state.
    128  * @param [mrb_value] self String to concatenate.
    129  * @param [mrb_value] other String to append to self.
     173 * @param mrb The current mruby state.
     174 * @param self String to concatenate.
     175 * @param other String to append to self.
    130176 * @return [mrb_value] Returns a new String appending other to self.
    131177 */
    132 MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
    133 
    134 /*
     178MRB_API void mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other);
     179
     180/**
    135181 * Adds two strings together.
    136182 *
    137183 *
    138  *  Example:
    139  *
    140  *     !!!c
     184 * Example:
     185 *
    141186 *     int
    142187 *     main(int argc,
     
    162207 *       mrb_p(mrb, b);
    163208 *
    164  *       // Concatnates both Ruby strings.
     209 *       // Concatenates both Ruby strings.
    165210 *       c = mrb_str_plus(mrb, a, b);
    166211 *
    167  *      // Prints new Concatnated Ruby string.
    168  *      mrb_p(mrb, c);
    169  *
    170  *      mrb_close(mrb);
    171  *      return 0;
    172  *    }
    173  *
    174  *
    175  *  Result:
     212 *       // Prints new Concatenated Ruby string.
     213 *       mrb_p(mrb, c);
     214 *
     215 *       mrb_close(mrb);
     216 *       return 0;
     217 *     }
     218 *
     219 *
     220 * Result:
    176221 *
    177222 *     => "abc"  # First string
    178223 *     => "def"  # Second string
    179  *     => "abcdef" # First & Second concatnated.
    180  *
    181  * @param [mrb_state] mrb The current mruby state.
    182  * @param [mrb_value] a First string to concatenate.
    183  * @param [mrb_value] b Second string to concatenate.
     224 *     => "abcdef" # First & Second concatenated.
     225 *
     226 * @param mrb The current mruby state.
     227 * @param a First string to concatenate.
     228 * @param b Second string to concatenate.
    184229 * @return [mrb_value] Returns a new String containing a concatenated to b.
    185230 */
    186 MRB_API mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
    187 
    188 /*
     231MRB_API mrb_value mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b);
     232
     233/**
    189234 * Converts pointer into a Ruby string.
    190235 *
    191  * @param [mrb_state] mrb The current mruby state.
    192  * @param [void*] p The pointer to convert to Ruby string.
     236 * @param mrb The current mruby state.
     237 * @param p The pointer to convert to Ruby string.
    193238 * @return [mrb_value] Returns a new Ruby String.
    194239 */
    195 MRB_API mrb_value mrb_ptr_to_str(mrb_state *, void*);
    196 
    197 /*
     240MRB_API mrb_value mrb_ptr_to_str(mrb_state *mrb, void *p);
     241
     242/**
    198243 * Returns an object as a Ruby string.
    199244 *
    200  * @param [mrb_state] mrb The current mruby state.
    201  * @param [mrb_value] obj An object to return as a Ruby string.
     245 * @param mrb The current mruby state.
     246 * @param obj An object to return as a Ruby string.
    202247 * @return [mrb_value] An object as a Ruby string.
    203248 */
    204249MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
    205250
    206 /*
     251/**
    207252 * Resizes the string's length. Returns the amount of characters
    208253 * in the specified by len.
     
    210255 * Example:
    211256 *
    212  *     !!!c
    213257 *     int
    214258 *     main(int argc,
     
    235279 * Result:
    236280 *
    237  *     => "Hello"
    238  *
    239  * @param [mrb_state] mrb The current mruby state.
    240  * @param [mrb_value] str The Ruby string to resize.
    241  * @param [mrb_value] len The length.
     281 *      => "Hello"
     282 *
     283 * @param mrb The current mruby state.
     284 * @param str The Ruby string to resize.
     285 * @param len The length.
    242286 * @return [mrb_value] An object as a Ruby string.
    243287 */
    244288MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
    245289
    246 /*
     290/**
    247291 * Returns a sub string.
    248292 *
    249  *  Example:
    250  *
    251  *     !!!c
     293 * Example:
     294 *
    252295 *     int
    253296 *     main(int argc,
     
    275318 *     }
    276319 *
    277  *  Result:
     320 * Result:
    278321 *
    279322 *     => "He"
    280323 *
    281  * @param [mrb_state] mrb The current mruby state.
    282  * @param [mrb_value] str Ruby string.
    283  * @param [mrb_int] beg The beginning point of the sub-string.
    284  * @param [mrb_int] len The end point of the sub-string.
     324 * @param mrb The current mruby state.
     325 * @param str Ruby string.
     326 * @param beg The beginning point of the sub-string.
     327 * @param len The end point of the sub-string.
    285328 * @return [mrb_value] An object as a Ruby sub-string.
    286329 */
    287330MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
    288331
    289 /*
     332/**
    290333 * Returns a Ruby string type.
    291334 *
    292335 *
    293  * @param [mrb_state] mrb The current mruby state.
    294  * @param [mrb_value] str Ruby string.
     336 * @param mrb The current mruby state.
     337 * @param str Ruby string.
    295338 * @return [mrb_value] A Ruby string.
    296339 */
     340MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str);
     341MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
     342/* obsolete: use mrb_ensure_string_type() instead */
    297343MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
    298344
    299 MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
     345
     346MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa);
    300347MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa);
    301348
    302 MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr);
     349/* NULL terminated C string from mrb_value */
     350MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str);
     351/* NULL terminated C string from mrb_value; `str` will be updated */
     352MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str);
     353/* obslete: use RSTRING_PTR() */
    303354MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str);
    304 /*
    305  * Returns the length of the Ruby string.
    306  *
    307  *
    308  * @param [mrb_state] mrb The current mruby state.
    309  * @param [mrb_value] str Ruby string.
    310  * @return [mrb_int] The length of the passed in Ruby string.
    311  */
     355/* obslete: use RSTRING_LEN() */
    312356MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str);
    313357
    314 /*
     358/**
    315359 * Duplicates a string object.
    316360 *
    317361 *
    318  * @param [mrb_state] mrb The current mruby state.
    319  * @param [mrb_value] str Ruby string.
     362 * @param mrb The current mruby state.
     363 * @param str Ruby string.
    320364 * @return [mrb_value] Duplicated Ruby string.
    321365 */
    322366MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str);
    323367
    324 /*
     368/**
    325369 * Returns a symbol from a passed in Ruby string.
    326370 *
    327  * @param [mrb_state] mrb The current mruby state.
    328  * @param [mrb_value] self Ruby string.
     371 * @param mrb The current mruby state.
     372 * @param self Ruby string.
    329373 * @return [mrb_value] A symbol.
    330374 */
     
    332376
    333377MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck);
     378MRB_API mrb_value mrb_cstr_to_inum(mrb_state *mrb, const char *s, mrb_int base, mrb_bool badcheck);
    334379MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck);
    335 
    336 /*
     380MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck);
     381
     382/**
    337383 * Returns a converted string type.
     384 * For type checking, non converting `mrb_to_str` is recommended.
    338385 */
    339386MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
    340387
    341 /*
     388/**
    342389 * Returns true if the strings match and false if the strings don't match.
    343390 *
    344  * @param [mrb_state] mrb The current mruby state.
    345  * @param [mrb_value] str1 Ruby string to compare.
    346  * @param [mrb_value] str2 Ruby string to compare.
     391 * @param mrb The current mruby state.
     392 * @param str1 Ruby string to compare.
     393 * @param str2 Ruby string to compare.
    347394 * @return [mrb_value] boolean value.
    348395 */
    349396MRB_API mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
    350397
    351 /*
    352  * Returns a concated string comprised of a Ruby string and a C string.
    353  *
    354  * @param [mrb_state] mrb The current mruby state.
    355  * @param [mrb_value] str Ruby string.
    356  * @param [const char *] ptr A C string.
    357  * @param [size_t] len length of C string.
     398/**
     399 * Returns a concatenated string comprised of a Ruby string and a C string.
     400 *
     401 * @param mrb The current mruby state.
     402 * @param str Ruby string.
     403 * @param ptr A C string.
     404 * @param len length of C string.
    358405 * @return [mrb_value] A Ruby string.
    359406 * @see mrb_str_cat_cstr
     
    361408MRB_API mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
    362409
    363 /*
    364  * Returns a concated string comprised of a Ruby string and a C string.
    365  *
    366  * @param [mrb_state] mrb The current mruby state.
    367  * @param [mrb_value] str Ruby string.
    368  * @param [const char *] ptr A C string.
     410/**
     411 * Returns a concatenated string comprised of a Ruby string and a C string.
     412 *
     413 * @param mrb The current mruby state.
     414 * @param str Ruby string.
     415 * @param ptr A C string.
    369416 * @return [mrb_value] A Ruby string.
    370417 * @see mrb_str_cat
     
    374421#define mrb_str_cat_lit(mrb, str, lit) mrb_str_cat(mrb, str, lit, mrb_strlen_lit(lit))
    375422
    376 /*
     423/**
    377424 * Adds str2 to the end of str1.
    378425 */
    379426MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
    380427
    381 /*
     428/**
    382429 * Returns 0 if both Ruby strings are equal. Returns a value < 0 if Ruby str1 is less than Ruby str2. Returns a value > 0 if Ruby str2 is greater than Ruby str1.
    383430 */
    384431MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
    385432
    386 /*
     433/**
    387434 * Returns a newly allocated C string from a Ruby string.
    388435 * This is an utility function to pass a Ruby string to C library functions.
     
    395442 *   (e.g. it can be used for mkstemp(3)).
    396443 *
    397  * @param [mrb_state *] mrb The current mruby state.
    398  * @param [mrb_value] str Ruby string. Must be an instance of String.
     444 * @param mrb The current mruby state.
     445 * @param str Ruby string. Must be an instance of String.
    399446 * @return [char *] A newly allocated C string.
    400447 */
    401448MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
    402449
    403 mrb_value mrb_str_pool(mrb_state *mrb, mrb_value str);
    404 mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str);
     450mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree);
     451uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
    405452mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
    406453
    407 /*
     454/**
    408455 * Returns a printable version of str, surrounded by quote marks, with special characters escaped.
    409456 */
    410457mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
    411 
    412 void mrb_noregexp(mrb_state *mrb, mrb_value self);
    413 void mrb_regexp_check(mrb_state *mrb, mrb_value obj);
    414458
    415459/* For backward compatibility */
     
    418462#define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2)
    419463
     464mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
     465mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
     466
     467#ifdef MRB_UTF8_STRING
     468mrb_int mrb_utf8len(const char *str, const char *end);
     469mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len);
     470#endif
     471
    420472MRB_END_DECL
    421473
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/throw.h

    r331 r439  
    1 /*
    2 ** mruby/throw.h - mruby exception throwing handler
     1/**
     2** @file mruby/throw.h - mruby exception throwing handler
    33**
    44** See Copyright Notice in mruby.h
     
    1616#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
    1717
    18 #define MRB_TRY(buf) do { try {
     18#define MRB_TRY(buf) try {
    1919#define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; }
    20 #define MRB_END_EXC(buf)  } } while(0)
     20#define MRB_END_EXC(buf)  }
    2121
    2222#define MRB_THROW(buf) throw((buf)->impl)
     
    3535#endif
    3636
    37 #define MRB_TRY(buf) do { if (MRB_SETJMP((buf)->impl) == 0) {
     37#define MRB_TRY(buf) if (MRB_SETJMP((buf)->impl) == 0) {
    3838#define MRB_CATCH(buf) } else {
    39 #define MRB_END_EXC(buf) } } while(0)
     39#define MRB_END_EXC(buf) }
    4040
    4141#define MRB_THROW(buf) MRB_LONGJMP((buf)->impl, 1);
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/value.h

    r331 r439  
    1 /*
    2 ** mruby/value.h - mruby value definitions
     1/**
     2** @file mruby/value.h - mruby value definitions
    33**
    44** See Copyright Notice in mruby.h
     
    1010#include "common.h"
    1111
    12 /**
     12/*
    1313 * MRuby Value definition functions and macros.
    1414 */
    1515MRB_BEGIN_DECL
    1616
     17/**
     18 * mruby Symbol.
     19 * @class mrb_sym
     20 *
     21 * You can create an mrb_sym by simply using mrb_str_intern() or mrb_intern_cstr()
     22 */
    1723typedef uint32_t mrb_sym;
     24
     25/**
     26 * mruby Boolean.
     27 * @class mrb_bool
     28 *
     29 *
     30 * Used internally to represent boolean. Can be TRUE or FALSE.
     31 * Not to be confused with Ruby's boolean classes, which can be
     32 * obtained using mrb_false_value() and mrb_true_value()
     33 */
    1834typedef uint8_t mrb_bool;
    1935struct mrb_state;
    20 
    21 #if defined(MRB_INT16) && defined(MRB_INT64)
    22 # error "You can't define MRB_INT16 and MRB_INT64 at the same time."
    23 #endif
    2436
    2537#if defined _MSC_VER && _MSC_VER < 1800
    2638# define PRIo64 "llo"
    2739# define PRId64 "lld"
     40# define PRIu64 "llu"
    2841# define PRIx64 "llx"
    2942# define PRIo16 "ho"
    3043# define PRId16 "hd"
     44# define PRIu16 "hu"
    3145# define PRIx16 "hx"
    3246# define PRIo32 "o"
    3347# define PRId32 "d"
     48# define PRIu32 "u"
    3449# define PRIx32 "x"
    3550#else
     
    4560# define MRB_PRId PRId64
    4661# define MRB_PRIx PRIx64
    47 #elif defined(MRB_INT16)
    48   typedef int16_t mrb_int;
    49 # define MRB_INT_BIT 16
    50 # define MRB_INT_MIN (INT16_MIN>>MRB_FIXNUM_SHIFT)
    51 # define MRB_INT_MAX (INT16_MAX>>MRB_FIXNUM_SHIFT)
    52 # define MRB_PRIo PRIo16
    53 # define MRB_PRId PRId16
    54 # define MRB_PRIx PRIx16
    5562#else
    5663  typedef int32_t mrb_int;
     
    6370#endif
    6471
    65 
     72#ifdef MRB_ENDIAN_BIG
     73# define MRB_ENDIAN_LOHI(a,b) a b
     74#else
     75# define MRB_ENDIAN_LOHI(a,b) b a
     76#endif
     77
     78#ifndef MRB_WITHOUT_FLOAT
    6679MRB_API double mrb_float_read(const char*, char**);
    6780#ifdef MRB_USE_FLOAT
     
    7083  typedef double mrb_float;
    7184#endif
     85#endif
    7286
    7387#if defined _MSC_VER && _MSC_VER < 1900
    74 # ifndef __cplusplus
    75 #  define inline __inline
    76 # endif
    7788# include <stdarg.h>
    7889MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg);
     
    8091# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
    8192# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
    82 # if _MSC_VER < 1800
     93# if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT
    8394#  include <float.h>
    8495#  define isfinite(n) _finite(n)
     
    94105enum mrb_vtype {
    95106  MRB_TT_FALSE = 0,   /*   0 */
    96   MRB_TT_FREE,        /*   1 */
    97   MRB_TT_TRUE,        /*   2 */
     107  MRB_TT_TRUE,        /*   1 */
     108  MRB_TT_FLOAT,       /*   2 */
    98109  MRB_TT_FIXNUM,      /*   3 */
    99110  MRB_TT_SYMBOL,      /*   4 */
    100111  MRB_TT_UNDEF,       /*   5 */
    101   MRB_TT_FLOAT,       /*   6 */
    102   MRB_TT_CPTR,        /*   7 */
     112  MRB_TT_CPTR,        /*   6 */
     113  MRB_TT_FREE,        /*   7 */
    103114  MRB_TT_OBJECT,      /*   8 */
    104115  MRB_TT_CLASS,       /*   9 */
     
    147158#endif
    148159
     160#define MRB_SYMBOL_BIT (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT)
     161#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT)
     162
     163#if INTPTR_MAX < MRB_INT_MAX
     164  typedef intptr_t mrb_ssize;
     165# define MRB_SSIZE_MAX (INTPTR_MAX>>MRB_FIXNUM_SHIFT)
     166#else
     167  typedef mrb_int mrb_ssize;
     168# define MRB_SSIZE_MAX MRB_INT_MAX
     169#endif
     170
     171#ifndef mrb_immediate_p
     172#define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE)
     173#endif
    149174#ifndef mrb_fixnum_p
    150175#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
    151176#endif
     177#ifndef mrb_symbol_p
     178#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
     179#endif
    152180#ifndef mrb_undef_p
    153181#define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
     
    156184#define mrb_nil_p(o)  (mrb_type(o) == MRB_TT_FALSE && !mrb_fixnum(o))
    157185#endif
     186#ifndef mrb_false_p
     187#define mrb_false_p(o) (mrb_type(o) == MRB_TT_FALSE && !!mrb_fixnum(o))
     188#endif
     189#ifndef mrb_true_p
     190#define mrb_true_p(o)  (mrb_type(o) == MRB_TT_TRUE)
     191#endif
     192#ifndef MRB_WITHOUT_FLOAT
     193#ifndef mrb_float_p
     194#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
     195#endif
     196#endif
     197#ifndef mrb_array_p
     198#define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
     199#endif
     200#ifndef mrb_string_p
     201#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
     202#endif
     203#ifndef mrb_hash_p
     204#define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
     205#endif
     206#ifndef mrb_cptr_p
     207#define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR)
     208#endif
     209#ifndef mrb_exception_p
     210#define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION)
     211#endif
     212#ifndef mrb_free_p
     213#define mrb_free_p(o) (mrb_type(o) == MRB_TT_FREE)
     214#endif
     215#ifndef mrb_object_p
     216#define mrb_object_p(o) (mrb_type(o) == MRB_TT_OBJECT)
     217#endif
     218#ifndef mrb_class_p
     219#define mrb_class_p(o) (mrb_type(o) == MRB_TT_CLASS)
     220#endif
     221#ifndef mrb_module_p
     222#define mrb_module_p(o) (mrb_type(o) == MRB_TT_MODULE)
     223#endif
     224#ifndef mrb_iclass_p
     225#define mrb_iclass_p(o) (mrb_type(o) == MRB_TT_ICLASS)
     226#endif
     227#ifndef mrb_sclass_p
     228#define mrb_sclass_p(o) (mrb_type(o) == MRB_TT_SCLASS)
     229#endif
     230#ifndef mrb_proc_p
     231#define mrb_proc_p(o) (mrb_type(o) == MRB_TT_PROC)
     232#endif
     233#ifndef mrb_range_p
     234#define mrb_range_p(o) (mrb_type(o) == MRB_TT_RANGE)
     235#endif
     236#ifndef mrb_file_p
     237#define mrb_file_p(o) (mrb_type(o) == MRB_TT_FILE)
     238#endif
     239#ifndef mrb_env_p
     240#define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV)
     241#endif
     242#ifndef mrb_data_p
     243#define mrb_data_p(o) (mrb_type(o) == MRB_TT_DATA)
     244#endif
     245#ifndef mrb_fiber_p
     246#define mrb_fiber_p(o) (mrb_type(o) == MRB_TT_FIBER)
     247#endif
     248#ifndef mrb_istruct_p
     249#define mrb_istruct_p(o) (mrb_type(o) == MRB_TT_ISTRUCT)
     250#endif
     251#ifndef mrb_break_p
     252#define mrb_break_p(o) (mrb_type(o) == MRB_TT_BREAK)
     253#endif
    158254#ifndef mrb_bool
    159255#define mrb_bool(o)   (mrb_type(o) != MRB_TT_FALSE)
    160256#endif
    161 #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
    162 #define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
    163 #define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
    164 #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
    165 #define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
    166 #define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR)
    167 #define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION)
    168257#define mrb_test(o)   mrb_bool(o)
    169 MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value);
    170 
    171 /*
     258
     259/**
    172260 * Returns a float in Ruby.
    173  */
     261 *
     262 * Takes a float and boxes it into an mrb_value
     263 */
     264#ifndef MRB_WITHOUT_FLOAT
    174265MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
    175266{
     
    179270  return v;
    180271}
    181 
    182 static inline mrb_value
     272#endif
     273
     274MRB_INLINE mrb_value
    183275mrb_cptr_value(struct mrb_state *mrb, void *p)
    184276{
     
    189281}
    190282
    191 /*
     283/**
    192284 * Returns a fixnum in Ruby.
     285 *
     286 * Takes an integer and boxes it into an mrb_value
    193287 */
    194288MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
     
    199293}
    200294
    201 static inline mrb_value
     295MRB_INLINE mrb_value
    202296mrb_symbol_value(mrb_sym i)
    203297{
     
    207301}
    208302
    209 static inline mrb_value
     303MRB_INLINE mrb_value
    210304mrb_obj_value(void *p)
    211305{
     
    217311}
    218312
    219 
    220 /*
     313/**
    221314 * Get a nil mrb_value object.
    222315 *
     
    231324}
    232325
    233 /*
     326/**
    234327 * Returns false in Ruby.
    235328 */
     
    241334}
    242335
    243 /*
     336/**
    244337 * Returns true in Ruby.
    245338 */
     
    251344}
    252345
    253 static inline mrb_value
     346MRB_INLINE mrb_value
    254347mrb_bool_value(mrb_bool boolean)
    255348{
     
    259352}
    260353
    261 static inline mrb_value
     354MRB_INLINE mrb_value
    262355mrb_undef_value(void)
    263356{
     
    267360}
    268361
    269 #ifdef MRB_USE_ETEXT_EDATA
    270 #if (defined(__APPLE__) && defined(__MACH__))
    271 #include <mach-o/getsect.h>
     362#if defined(MRB_USE_ETEXT_EDATA) && !defined(MRB_USE_LINK_TIME_RO_DATA_P)
     363# ifdef __GNUC__
     364#  warning MRB_USE_ETEXT_EDATA is deprecated. Define MRB_USE_LINK_TIME_RO_DATA_P instead.
     365# endif
     366# define MRB_USE_LINK_TIME_RO_DATA_P
     367#endif
     368
     369#if defined(MRB_USE_CUSTOM_RO_DATA_P)
     370/* If you define `MRB_USE_CUSTOM_RO_DATA_P`, you must implement `mrb_ro_data_p()`. */
     371mrb_bool mrb_ro_data_p(const char *p);
     372#elif defined(MRB_USE_LINK_TIME_RO_DATA_P)
     373extern char __ehdr_start[];
     374extern char __init_array_start[];
     375
    272376static inline mrb_bool
    273377mrb_ro_data_p(const char *p)
    274378{
    275   return (const char*)get_etext() < p && p < (const char*)get_edata();
    276 }
    277 #else
    278 extern char _etext[];
    279 #ifdef MRB_NO_INIT_ARRAY_START
    280 extern char _edata[];
    281 
    282 static inline mrb_bool
    283 mrb_ro_data_p(const char *p)
    284 {
    285   return _etext < p && p < _edata;
    286 }
    287 #else
    288 extern char __init_array_start[];
    289 
    290 static inline mrb_bool
    291 mrb_ro_data_p(const char *p)
    292 {
    293   return _etext < p && p < (char*)&__init_array_start;
    294 }
    295 #endif
    296 #endif
     379  return __ehdr_start < p && p < __init_array_start;
     380}
    297381#else
    298382# define mrb_ro_data_p(p) FALSE
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/variable.h

    r331 r439  
    1 /*
    2 ** mruby/variable.h - mruby variables
     1/**
     2** @file mruby/variable.h - mruby variables
    33**
    44** See Copyright Notice in mruby.h
     
    3232mrb_value mrb_vm_special_get(mrb_state*, mrb_sym);
    3333void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value);
    34 mrb_value mrb_vm_iv_get(mrb_state*, mrb_sym);
    35 void mrb_vm_iv_set(mrb_state*, mrb_sym, mrb_value);
    3634mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym);
    3735void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value);
     
    4341MRB_API void mrb_const_remove(mrb_state*, mrb_value, mrb_sym);
    4442
    45 MRB_API mrb_bool mrb_iv_p(mrb_state *mrb, mrb_sym sym);
    46 MRB_API void mrb_iv_check(mrb_state *mrb, mrb_sym sym);
     43MRB_API mrb_bool mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym sym);
     44MRB_API void mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym sym);
    4745MRB_API mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
    4846MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
    4947MRB_API mrb_bool mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
    50 MRB_API void mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
    5148MRB_API mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym);
    5249MRB_API void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v);
     
    10198 * Example:
    10299 *
    103  *     !!!ruby
    104100 *     # Ruby style
    105101 *     $value = nil
    106102 *
    107  *     !!!c
    108103 *     // C style
    109104 *     mrb_sym sym = mrb_intern_lit(mrb, "$value");
     
    112107 * @param mrb The mruby state reference
    113108 * @param sym The name of the global variable
    114  * @param val The value of the global variable
    115109 */
    116110MRB_API void mrb_gv_remove(mrb_state *mrb, mrb_sym sym);
     
    121115MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym);
    122116mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*);
     117void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
    123118mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod);
    124119mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
     
    127122mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym);
    128123mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym);
    129 mrb_sym mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer);
     124mrb_bool mrb_ident_p(const char *s, mrb_int len);
    130125
    131126/* GC functions */
     
    136131void mrb_gc_free_iv(mrb_state*, struct RObject*);
    137132
     133/* return non zero to break the loop */
     134typedef int (mrb_iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
     135MRB_API void mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p);
     136
    138137MRB_END_DECL
    139138
  • EcnlProtoTool/trunk/mruby-2.1.1/include/mruby/version.h

    r331 r439  
    1 /*
    2 ** mruby/version.h - mruby version definition
     1/**
     2** @file mruby/version.h - mruby version definition
    33**
    44** See Copyright Notice in mruby.h
     
    2828 * The version of Ruby used by mruby.
    2929 */
    30 #define MRUBY_RUBY_VERSION "1.9"
     30#define MRUBY_RUBY_VERSION "2.0"
    3131
    3232/*
     
    3838 * Major release version number.
    3939 */
    40 #define MRUBY_RELEASE_MAJOR 1
     40#define MRUBY_RELEASE_MAJOR 2
    4141
    4242/*
    4343 * Minor release version number.
    4444 */
    45 #define MRUBY_RELEASE_MINOR 3
     45#define MRUBY_RELEASE_MINOR 1
    4646
    4747/*
    4848 * Tiny release version number.
    4949 */
    50 #define MRUBY_RELEASE_TEENY 0
     50#define MRUBY_RELEASE_TEENY 1
    5151
    5252/*
     
    6363 * Release year.
    6464 */
    65 #define MRUBY_RELEASE_YEAR 2017
     65#define MRUBY_RELEASE_YEAR 2020
    6666
    6767/*
    6868 * Release month.
    6969 */
    70 #define MRUBY_RELEASE_MONTH 7
     70#define MRUBY_RELEASE_MONTH 6
    7171
    7272/*
     
    7878 * Release date as a string.
    7979 */
    80 #define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
     80#define MRUBY_RELEASE_DATE    \
     81  MRUBY_RELEASE_YEAR_STR "-"  \
     82  MRUBY_RELEASE_MONTH_STR "-" \
     83  MRUBY_RELEASE_DAY_STR
     84#define MRUBY_RELEASE_YEAR_STR MRB_STRINGIZE(MRUBY_RELEASE_YEAR)
     85#if MRUBY_RELEASE_MONTH < 10
     86#define MRUBY_RELEASE_MONTH_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_MONTH)
     87#else
     88#define MRUBY_RELEASE_MONTH_STR MRB_STRINGIZE(MRUBY_RELEASE_MONTH)
     89#endif
     90#if MRUBY_RELEASE_DAY < 10
     91#define MRUBY_RELEASE_DAY_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
     92#else
     93#define MRUBY_RELEASE_DAY_STR MRB_STRINGIZE(MRUBY_RELEASE_DAY)
     94#endif
    8195
    8296/*
     
    93107 * mruby's version, and release date.
    94108 */
    95 #define MRUBY_DESCRIPTION      \
    96   "mruby " MRUBY_VERSION       \
    97   " (" MRUBY_RELEASE_DATE ") " \
     109#define MRUBY_DESCRIPTION     \
     110  "mruby " MRUBY_VERSION      \
     111  " (" MRUBY_RELEASE_DATE ")" \
    98112
    99113/*
  • EcnlProtoTool/trunk/mruby-2.1.1/lib/mruby/source.rb

    r321 r439  
    77
    88    # Reads a constant defined at version.h
    9     MRUBY_READ_VERSION_CONSTANT = Proc.new { |name| ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?$/)[1] }
     9    MRUBY_READ_VERSION_CONSTANT = Proc.new do |name|
     10      ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?\r?$/)[1]
     11    end
    1012
    1113    MRUBY_RUBY_VERSION = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_VERSION']
  • EcnlProtoTool/trunk/mruby-2.1.1/minirake

    r331 r439  
    1 #!/usr/bin/env ruby
    2 
    3 # Original is https://github.com/jimweirich/rake/
    4 # Copyright (c) 2003 Jim Weirich
    5 # License: MIT-LICENSE
    6 
    7 require 'getoptlong'
    8 require 'fileutils'
    9 
    10 class String
    11   def ext(newext='')
    12     return self.dup if ['.', '..'].include? self
    13     if newext != ''
    14       newext = (newext =~ /^\./) ? newext : ("." + newext)
    15     end
    16     self.chomp(File.extname(self)) << newext
    17   end
    18 
    19   def pathmap(spec=nil, &block)
    20     return self if spec.nil?
    21     result = ''
    22     spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
    23       case frag
    24       when '%f'
    25         result << File.basename(self)
    26       when '%n'
    27         result << File.basename(self).ext
    28       when '%d'
    29         result << File.dirname(self)
    30       when '%x'
    31         result << File.extname(self)
    32       when '%X'
    33         result << self.ext
    34       when '%p'
    35         result << self
    36       when '%s'
    37         result << (File::ALT_SEPARATOR || File::SEPARATOR)
    38       when '%-'
    39         # do nothing
    40       when '%%'
    41         result << "%"
    42       when /%(-?\d+)d/
    43         result << pathmap_partial($1.to_i)
    44       when /^%\{([^}]*)\}(\d*[dpfnxX])/
    45         patterns, operator = $1, $2
    46         result << pathmap('%' + operator).pathmap_replace(patterns, &block)
    47       when /^%/
    48         fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
    49       else
    50         result << frag
    51       end
    52     end
    53     result
    54   end
    55 end
    56 
    57 module MiniRake
    58   class Task
    59     TASKS = Hash.new
    60     RULES = Array.new
    61 
    62     # List of prerequisites for a task.
    63     attr_reader :prerequisites
    64 
    65     # Source dependency for rule synthesized tasks.  Nil if task was not
    66     # sythesized from a rule.
    67     attr_accessor :source
    68 
    69     # Create a task named +task_name+ with no actions or prerequisites..
    70     # use +enhance+ to add actions and prerequisites.
    71     def initialize(task_name)
    72       @name = task_name
    73       @prerequisites = []
    74       @actions = []
    75     end
    76 
    77     # Enhance a task with prerequisites or actions.  Returns self.
    78     def enhance(deps=nil, &block)
    79       @prerequisites |= deps if deps
    80       @actions << block if block_given?
    81       self
    82     end
    83 
    84     # Name of the task.
    85     def name
    86       @name.to_s
    87     end
    88 
    89     # Invoke the task if it is needed.  Prerequites are invoked first.
    90     def invoke
    91       puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace
    92       return if @already_invoked
    93       @already_invoked = true
    94       prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
    95       prerequisites.each { |n| Task[n].invoke }
    96       execute if needed?
    97     end
    98 
    99     # Execute the actions associated with this task.
    100     def execute
    101       puts "Execute #{name}" if $trace
    102       self.class.enhance_with_matching_rule(name) if @actions.empty?
    103       unless $dryrun
    104         @actions.each { |act| act.call(self) }
    105       end
    106     end
    107 
    108     # Is this task needed?
    109     def needed?
    110       true
    111     end
    112 
    113     # Timestamp for this task.  Basic tasks return the current time for
    114     # their time stamp.  Other tasks can be more sophisticated.
    115     def timestamp
    116       Time.now
    117     end
    118 
    119     # Class Methods ----------------------------------------------------
    120 
    121     class << self
    122 
    123       # Clear the task list.  This cause rake to immediately forget all
    124       # the tasks that have been assigned.  (Normally used in the unit
    125       # tests.)
    126       def clear
    127         TASKS.clear
    128         RULES.clear
    129       end
    130 
    131       # List of all defined tasks.
    132       def tasks
    133         TASKS.keys.sort.collect { |tn| Task[tn] }
    134       end
    135 
    136       # Return a task with the given name.  If the task is not currently
    137       # known, try to synthesize one from the defined rules.  If no
    138       # rules are found, but an existing file matches the task name,
    139       # assume it is a file task with no dependencies or actions.
    140       def [](task_name)
    141         task_name = task_name.to_s
    142         if task_name.end_with?(":")
    143           task_name = task_name.slice(0, task_name.length - 1)
    144         end
    145         if task = TASKS[task_name]
    146           return task
    147         end
    148         if task = enhance_with_matching_rule(task_name)
    149           return task
    150         end
    151         if File.exist?(task_name)
    152           return FileTask.define_task(task_name)
    153         end
    154         fail "Don't know how to rake #{task_name}"
    155       end
    156 
    157       # Define a task given +args+ and an option block.  If a rule with
    158       # the given name already exists, the prerequisites and actions are
    159       # added to the existing task.
    160       def define_task(args, &block)
    161         task_name, deps = resolve_args(args)
    162         lookup(task_name).enhance([deps].flatten, &block)
    163       end
    164 
    165       # Define a rule for synthesizing tasks.
    166       def create_rule(args, &block)
    167         pattern, deps = resolve_args(args)
    168         pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
    169         RULES << [pattern, deps, block]
    170       end
    171 
    172 
    173       # Lookup a task.  Return an existing task if found, otherwise
    174       # create a task of the current type.
    175       def lookup(task_name)
    176         name = task_name.to_s
    177         TASKS[name] ||= self.new(name)
    178       end
    179 
    180       # If a rule can be found that matches the task name, enhance the
    181       # task with the prerequisites and actions from the rule.  Set the
    182       # source attribute of the task appropriately for the rule.  Return
    183       # the enhanced task or nil of no rule was found.
    184       def enhance_with_matching_rule(task_name)
    185         RULES.each do |pattern, extensions, block|
    186           if pattern.match(task_name)
    187             ext = extensions.first
    188             deps = extensions[1..-1]
    189             case ext
    190             when String
    191               source = task_name.sub(/\.[^.]*$/, ext)
    192             when Proc
    193               source = ext.call(task_name)
    194             else
    195               fail "Don't know how to handle rule dependent: #{ext.inspect}"
    196             end
    197             if File.exist?(source)
    198               task = FileTask.define_task({task_name => [source]+deps}, &block)
    199               task.source = source
    200               return task
    201             end
    202           end
    203         end
    204         nil
    205       end
    206 
    207       private
    208 
    209       # Resolve the arguments for a task/rule.
    210       def resolve_args(args)
    211         case args
    212         when Hash
    213           fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1
    214           fail "No Task Name Given" if args.size < 1
    215           task_name = args.keys[0]
    216           deps = args[task_name]
    217           deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps)
    218         else
    219           task_name = args
    220           deps = []
    221         end
    222         [task_name, deps]
    223       end
    224     end
    225   end
    226 
    227 
    228   ######################################################################
    229   class FileTask < Task
    230     # Is this file task needed?  Yes if it doesn't exist, or if its time
    231     # stamp is out of date.
    232     def needed?
    233       return true unless File.exist?(name)
    234       prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
    235       latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max
    236       return false if latest_prereq.nil?
    237       timestamp < latest_prereq
    238     end
    239 
    240     # Time stamp for file task.
    241     def timestamp
    242       return Time.at(0) unless File.exist?(name)
    243       stat = File::stat(name.to_s)
    244       stat.directory? ? Time.at(0) : stat.mtime
    245     end
    246   end
    247 
    248   module DSL
    249     # Declare a basic task.
    250     def task(args, &block)
    251       MiniRake::Task.define_task(args, &block)
    252     end
    253 
    254     # Declare a file task.
    255     def file(args, &block)
    256       MiniRake::FileTask.define_task(args, &block)
    257     end
    258 
    259     # Declare a set of files tasks to create the given directories on
    260     # demand.
    261     def directory(args, &block)
    262       MiniRake::FileTask.define_task(args) do |t|
    263         block.call(t) unless block.nil?
    264         dir = args.is_a?(Hash) ? args.keys.first : args
    265         (dir.split(File::SEPARATOR) + ['']).inject do |acc, part|
    266           (acc + File::SEPARATOR).tap do |d|
    267             Dir.mkdir(d) unless File.exists? d
    268           end + part
    269         end
    270       end
    271     end
    272 
    273     # Declare a rule for auto-tasks.
    274     def rule(args, &block)
    275       MiniRake::Task.create_rule(args, &block)
    276     end
    277 
    278     # Write a message to standard out if $verbose is enabled.
    279     def log(msg)
    280       print "  " if $trace && $verbose
    281       puts msg if $verbose
    282     end
    283 
    284     # Run the system command +cmd+.
    285     def sh(cmd)
    286       puts cmd if $verbose
    287       system(cmd) or fail "Command Failed: [#{cmd}]"
    288     end
    289 
    290     def desc(text)
    291     end
    292   end
    293 end
    294 
    295 Rake = MiniRake
    296 extend MiniRake::DSL
    297 
    298 
    299 ######################################################################
    300 # Task Definition Functions ...
    301 
    302 ######################################################################
    303 # Rake main application object.  When invoking +rake+ from the command
    304 # line, a RakeApp object is created and run.
    305 #
    306 class RakeApp
    307   RAKEFILES = ['rakefile', 'Rakefile']
    308 
    309   OPTIONS = [
    310     ['--dry-run',  '-n', GetoptLong::NO_ARGUMENT,
    311       "Do a dry run without executing actions."],
    312     ['--help',     '-H', GetoptLong::NO_ARGUMENT,
    313       "Display this help message."],
    314     ['--libdir',   '-I', GetoptLong::REQUIRED_ARGUMENT,
    315       "Include LIBDIR in the search path for required modules."],
    316     ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
    317       "Do not search parent directories for the Rakefile."],
    318     ['--quiet',    '-q', GetoptLong::NO_ARGUMENT,
    319       "Do not log messages to standard output (default)."],
    320     ['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT,
    321       "Use FILE as the rakefile."],
    322     ['--require',  '-r', GetoptLong::REQUIRED_ARGUMENT,
    323       "Require MODULE before executing rakefile."],
    324     ['--tasks',    '-T', GetoptLong::NO_ARGUMENT,
    325       "Display the tasks and dependencies, then exit."],
    326     ['--pull-gems','-p', GetoptLong::NO_ARGUMENT,
    327       "Pull all git mrbgems."],
    328     ['--trace',    '-t', GetoptLong::NO_ARGUMENT,
    329       "Turn on invoke/execute tracing."],
    330     ['--usage',    '-h', GetoptLong::NO_ARGUMENT,
    331       "Display usage."],
    332     ['--verbose',  '-v', GetoptLong::NO_ARGUMENT,
    333       "Log message to standard output."],
    334     ['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT,
    335       "Change executing directory of rakefiles."]
    336   ]
    337 
    338   # Create a RakeApp object.
    339   def initialize
    340     @rakefile = nil
    341     @nosearch = false
    342   end
    343 
    344   # True if one of the files in RAKEFILES is in the current directory.
    345   # If a match is found, it is copied into @rakefile.
    346   def have_rakefile
    347     RAKEFILES.each do |fn|
    348       if File.exist?(fn)
    349         @rakefile = fn
    350         return true
    351       end
    352     end
    353     return false
    354   end
    355 
    356   # Display the program usage line.
    357   def usage
    358       puts "rake [-f rakefile] {options} targets..."
    359   end
    360 
    361   # Display the rake command line help.
    362   def help
    363     usage
    364     puts
    365     puts "Options are ..."
    366     puts
    367     OPTIONS.sort.each do |long, short, mode, desc|
    368       if mode == GetoptLong::REQUIRED_ARGUMENT
    369         if desc =~ /\b([A-Z]{2,})\b/
    370           long = long + "=#{$1}"
    371         end
    372       end
    373       printf "  %-20s (%s)\n", long, short
    374       printf "      %s\n", desc
    375     end
    376   end
    377 
    378   # Display the tasks and dependencies.
    379   def display_tasks
    380     MiniRake::Task.tasks.each do |t|
    381       puts "#{t.class} #{t.name}"
    382       t.prerequisites.each { |pre| puts "    #{pre}" }
    383     end
    384   end
    385 
    386   # Return a list of the command line options supported by the
    387   # program.
    388   def command_line_options
    389     OPTIONS.collect { |lst| lst[0..-2] }
    390   end
    391 
    392   # Do the option defined by +opt+ and +value+.
    393   def do_option(opt, value)
    394     case opt
    395     when '--dry-run'
    396       $dryrun = true
    397       $trace = true
    398     when '--help'
    399       help
    400       exit
    401     when '--libdir'
    402       $:.push(value)
    403     when '--nosearch'
    404       @nosearch = true
    405     when '--quiet'
    406       $verbose = false
    407     when '--rakefile'
    408       RAKEFILES.clear
    409       RAKEFILES << value
    410     when '--require'
    411       require value
    412     when '--tasks'
    413       $show_tasks = true
    414     when '--pull-gems'
    415       $pull_gems = true
    416     when '--trace'
    417       $trace = true
    418     when '--usage'
    419       usage
    420       exit
    421     when '--verbose'
    422       $verbose = true
    423     when '--version'
    424       puts "rake, version #{RAKEVERSION}"
    425       exit
    426     when '--directory'
    427       Dir.chdir value
    428     else
    429       fail "Unknown option: #{opt}"
    430     end
    431   end
    432 
    433   # Read and handle the command line options.
    434   def handle_options
    435     $verbose = false
    436     $pull_gems = false
    437     opts = GetoptLong.new(*command_line_options)
    438     opts.each { |opt, value| do_option(opt, value) }
    439   end
    440 
    441   # Run the +rake+ application.
    442   def run
    443     handle_options
    444     begin
    445       here = Dir.pwd
    446       while ! have_rakefile
    447         Dir.chdir("..")
    448         if Dir.pwd == here || @nosearch
    449           fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})"
    450         end
    451         here = Dir.pwd
    452       end
    453       tasks = []
    454       ARGV.each do |task_name|
    455         if /^(\w+)=(.*)/.match(task_name)
    456           ENV[$1] = $2
    457         else
    458           tasks << task_name
    459         end
    460       end
    461       puts "(in #{Dir.pwd})"
    462       $rakefile = @rakefile
    463       load @rakefile
    464       if $show_tasks
    465         display_tasks
    466       else
    467         tasks.push("default") if tasks.size == 0
    468         tasks.each do |task_name|
    469           MiniRake::Task[task_name].invoke
    470         end
    471       end
    472     rescue Exception => ex
    473       puts "rake aborted!"
    474       puts ex.message
    475       if $trace
    476         puts ex.backtrace.join("\n")
    477       else
    478         puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
    479       end
    480       exit 1
    481     end
    482   end
    483 end
    484 
    485 if __FILE__ == $0 then
    486   RakeApp.new.run
    487 end
     1#! /usr/bin/env ruby
     2exec "rake", *ARGV
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/default.gembox

    r331 r439  
    11MRuby::GemBox.new do |conf|
     2  # Meta-programming features
     3  conf.gem :core => "mruby-metaprog"
     4
     5  # Use standard IO/File class
     6  conf.gem :core => "mruby-io"
     7
     8  # Use standard Array#pack, String#unpack methods
     9  conf.gem :core => "mruby-pack"
     10
    211  # Use standard Kernel#sprintf method
    312  conf.gem :core => "mruby-sprintf"
     
    1423  # Use standard Struct class
    1524  conf.gem :core => "mruby-struct"
     25
     26  # Use Comparable module extension
     27  conf.gem :core => "mruby-compar-ext"
    1628
    1729  # Use Enumerable module extension
     
    7587  conf.gem :core => "mruby-class-ext"
    7688
     89  # Use Method/UnboundMethod class
     90  conf.gem :core => "mruby-method"
     91
    7792  # Use mruby-compiler to build other mrbgems
    7893  conf.gem :core => "mruby-compiler"
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/mrblib/array.rb

    r331 r439  
    11class Array
    2   ##
    3   # call-seq:
    4   #    Array.try_convert(obj) -> array or nil
    5   #
    6   # Tries to convert +obj+ into an array, using +to_ary+ method.
    7   # converted array or +nil+ if +obj+ cannot be converted for any reason.
    8   # This method can be used to check if an argument is an array.
    9   #
    10   #    Array.try_convert([1])   #=> [1]
    11   #    Array.try_convert("1")   #=> nil
    12   #
    13   #    if tmp = Array.try_convert(arg)
    14   #      # the argument is an array
    15   #    elsif tmp = String.try_convert(arg)
    16   #      # the argument is a string
    17   #    end
    18   #
    19   def self.try_convert(obj)
    20     if obj.respond_to?(:to_ary)
    21       obj.to_ary
    22     else
    23       nil
    24     end
    25   end
    26 
    272  ##
    283  # call-seq:
     
    4217  #
    4318  def uniq!(&block)
    44     ary = self.dup
    45     result = []
     19    hash = {}
    4620    if block
     21      self.each do |val|
     22        key = block.call(val)
     23        hash[key] = val unless hash.key?(key)
     24      end
     25      result = hash.values
     26    else
    4727      hash = {}
    48       while ary.size > 0
    49         val = ary.shift
    50         key = block.call(val)
    51         hash[key] = val unless hash.has_key?(key)
    52       end
    53       hash.each_value do |value|
    54         result << value
    55       end
    56     else
    57       while ary.size > 0
    58         result << ary.shift
    59         ary.delete(result.last)
    60       end
     28      self.each do |val|
     29        hash[val] = val
     30      end
     31      result = hash.keys
    6132    end
    6233    if result.size == self.size
     
    8253  def uniq(&block)
    8354    ary = self.dup
    84     if block
    85       ary.uniq!(&block)
    86     else
    87       ary.uniq!
    88     end
     55    ary.uniq!(&block)
    8956    ary
    9057  end
     
    10673    hash = {}
    10774    array = []
    108     elem.each { |x| hash[x] = true }
    109     self.each { |x| array << x unless hash[x] }
     75    idx = 0
     76    len = elem.size
     77    while idx < len
     78      hash[elem[idx]] = true
     79      idx += 1
     80    end
     81    idx = 0
     82    len = size
     83    while idx < len
     84      v = self[idx]
     85      array << v unless hash[v]
     86      idx += 1
     87    end
    11088    array
     89  end
     90
     91  ##
     92  # call-seq:
     93  #    ary.difference(other_ary1, other_ary2, ...)   -> new_ary
     94  #
     95  # Returns a new array that is a copy of the original array, removing all
     96  # occurrences of any item that also appear in +other_ary+. The order is
     97  # preserved from the original array.
     98  #
     99  def difference(*args)
     100    ary = self
     101    args.each do |x|
     102      ary = ary - x
     103    end
     104    ary
    111105  end
    112106
     
    130124  ##
    131125  # call-seq:
     126  #    ary.union(other_ary,...)  -> new_ary
     127  #
     128  # Set Union---Returns a new array by joining this array with
     129  # <i>other_ary</i>, removing duplicates.
     130  #
     131  #    ["a", "b", "c"].union(["c", "d", "a"], ["a", "c", "e"])
     132  #           #=> ["a", "b", "c", "d", "e"]
     133  #
     134  def union(*args)
     135    ary = self.dup
     136    args.each do |x|
     137      ary.concat(x)
     138      ary.uniq!
     139    end
     140    ary
     141  end
     142
     143  ##
     144  # call-seq:
    132145  #    ary & other_ary      -> new_ary
    133146  #
     
    142155    hash = {}
    143156    array = []
    144     elem.each{|v| hash[v] = true }
    145     self.each do |v|
     157    idx = 0
     158    len = elem.size
     159    while idx < len
     160      hash[elem[idx]] = true
     161      idx += 1
     162    end
     163    idx = 0
     164    len = size
     165    while idx < len
     166      v = self[idx]
    146167      if hash[v]
    147168        array << v
    148169        hash.delete v
    149170      end
     171      idx += 1
    150172    end
    151173    array
     174  end
     175
     176  ##
     177  # call-seq:
     178  #    ary.intersection(other_ary,...)  -> new_ary
     179  #
     180  # Set Intersection---Returns a new array containing elements common to
     181  # this array and <i>other_ary</i>s, removing duplicates. The order is
     182  # preserved from the original array.
     183  #
     184  #    [1, 2, 3].intersection([3, 4, 1], [1, 3, 5])  #=> [1, 3]
     185  #
     186  def intersection(*args)
     187    ary = self
     188    args.each do |x|
     189      ary = ary & x
     190    end
     191    ary
    152192  end
    153193
     
    170210  #
    171211  def flatten(depth=nil)
    172     ar = []
    173     self.each do |e|
    174       if e.is_a?(Array) && (depth.nil? || depth > 0)
    175         ar += e.flatten(depth.nil? ? nil : depth - 1)
    176       else
    177         ar << e
    178       end
    179     end
    180     ar
     212    res = dup
     213    res.flatten! depth
     214    res
    181215  end
    182216
     
    201235    modified = false
    202236    ar = []
    203     self.each do |e|
     237    idx = 0
     238    len = size
     239    while idx < len
     240      e = self[idx]
    204241      if e.is_a?(Array) && (depth.nil? || depth > 0)
    205242        ar += e.flatten(depth.nil? ? nil : depth - 1)
     
    208245        ar << e
    209246      end
     247      idx += 1
    210248    end
    211249    if modified
     
    253291  # for efficiency
    254292  def reverse_each(&block)
    255     return to_enum :reverse_each unless block_given?
     293    return to_enum :reverse_each unless block
    256294
    257295    i = self.size - 1
     
    263301  end
    264302
    265   NONE=Object.new
    266303  ##
    267304  #  call-seq:
     
    288325  #
    289326
    290   def fetch(n=nil, ifnone=NONE, &block)
     327  def fetch(n, ifnone=NONE, &block)
    291328    warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block
    292329
     
    475512
    476513  def delete_if(&block)
    477     return to_enum :delete_if unless block_given?
     514    return to_enum :delete_if unless block
    478515
    479516    idx = 0
     
    504541
    505542  def reject!(&block)
    506     return to_enum :reject! unless block_given?
     543    return to_enum :reject! unless block
    507544
    508545    len = self.size
     
    594631
    595632  def bsearch(&block)
    596     return to_enum :bsearch unless block_given?
     633    return to_enum :bsearch unless block
     634
     635    if idx = bsearch_index(&block)
     636      self[idx]
     637    else
     638      nil
     639    end
     640  end
     641
     642  ##
     643  #  call-seq:
     644  #     ary.bsearch_index {|x| block }  -> int or nil
     645  #
     646  #  By using binary search, finds an index of a value from this array which
     647  #  meets the given condition in O(log n) where n is the size of the array.
     648  #
     649  #  It supports two modes, depending on the nature of the block and they are
     650  #  exactly the same as in the case of #bsearch method with the only difference
     651  #  being that this method returns the index of the element instead of the
     652  #  element itself. For more details consult the documentation for #bsearch.
     653
     654  def bsearch_index(&block)
     655    return to_enum :bsearch_index unless block
    597656
    598657    low = 0
    599     high = self.size
     658    high = size
    600659    satisfied = false
     660
    601661    while low < high
    602       mid = low + ((high - low) / 2).truncate
    603       val = self[mid]
    604       v = block.call(val)
    605       if v.is_a?(Integer)
    606         return val if v == 0
    607         smaller = v < 0
    608       elsif v == true
     662      mid = ((low+high)/2).truncate
     663      res = block.call self[mid]
     664
     665      case res
     666      when 0 # find-any mode: Found!
     667        return mid
     668      when Numeric # find-any mode: Continue...
     669        in_lower_half = res < 0
     670      when true # find-min mode
     671        in_lower_half = true
    609672        satisfied = true
    610         smaller = true
    611       elsif v == false || v.nil?
    612         smaller = false
    613       end
    614       if smaller
     673      when false, nil # find-min mode
     674        in_lower_half = false
     675      else
     676        raise TypeError, 'invalid block result (must be numeric, true, false or nil)'
     677      end
     678
     679      if in_lower_half
    615680        high = mid
    616681      else
     
    618683      end
    619684    end
    620     return nil if low == self.size
    621     return nil unless satisfied
    622     self[low]
    623   end
    624 
    625   ##
    626   #  call-seq:
    627   #     ary.delete_if { |item| block }  -> ary
    628   #     ary.delete_if                   -> Enumerator
    629   #
    630   #  Deletes every element of +self+ for which block evaluates to +true+.
    631   #
    632   #  The array is changed instantly every time the block is called, not after
    633   #  the iteration is over.
    634   #
    635   #  See also Array#reject!
    636   #
    637   #  If no block is given, an Enumerator is returned instead.
    638   #
    639   #     scores = [ 97, 42, 75 ]
    640   #     scores.delete_if {|score| score < 80 }   #=> [97]
    641 
    642   def delete_if(&block)
    643     return to_enum :delete_if unless block_given?
    644 
    645     idx = 0
    646     while idx < self.size do
    647       if block.call(self[idx])
    648         self.delete_at(idx)
    649       else
    650         idx += 1
    651       end
    652     end
    653     self
     685
     686    satisfied ? low : nil
    654687  end
    655688
     
    670703
    671704  def keep_if(&block)
    672     return to_enum :keep_if unless block_given?
     705    return to_enum :keep_if unless block
    673706
    674707    idx = 0
     
    699732
    700733  def select!(&block)
    701     return to_enum :select! unless block_given?
     734    return to_enum :select! unless block
    702735
    703736    result = []
    704     self.each do |x|
    705       result << x if block.call(x)
    706     end
    707     return nil if self.size == result.size
     737    idx = 0
     738    len = size
     739    while idx < len
     740      elem = self[idx]
     741      result << elem if block.call(elem)
     742      idx += 1
     743    end
     744    return nil if len == result.size
    708745    self.replace(result)
    709746  end
     
    727764    if block
    728765      idx = 0
    729       self.each do |*e|
    730         return idx if block.call(*e)
     766      len = size
     767      while idx < len
     768        return idx if block.call self[idx]
    731769        idx += 1
    732770      end
     
    735773    end
    736774    nil
    737   end
    738 
    739   ##
    740   #  call-seq:
    741   #     ary.to_ary -> ary
    742   #
    743   #  Returns +self+.
    744   #
    745   def to_ary
    746     self
    747775  end
    748776
     
    763791    end
    764792  end
     793
     794  ##
     795  # call-seq:
     796  #    ary.permutation { |p| block }          -> ary
     797  #    ary.permutation                        -> Enumerator
     798  #    ary.permutation(n) { |p| block }       -> ary
     799  #    ary.permutation(n)                     -> Enumerator
     800  #
     801  # When invoked with a block, yield all permutations of length +n+ of the
     802  # elements of the array, then return the array itself.
     803  #
     804  # If +n+ is not specified, yield all permutations of all elements.
     805  #
     806  # The implementation makes no guarantees about the order in which the
     807  # permutations are yielded.
     808  #
     809  # If no block is given, an Enumerator is returned instead.
     810  #
     811  # Examples:
     812  #
     813  #  a = [1, 2, 3]
     814  #  a.permutation.to_a    #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
     815  #  a.permutation(1).to_a #=> [[1],[2],[3]]
     816  #  a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
     817  #  a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
     818  #  a.permutation(0).to_a #=> [[]] # one permutation of length 0
     819  #  a.permutation(4).to_a #=> []   # no permutations of length 4
     820  def permutation(n=self.size, &block)
     821    return to_enum(:permutation, n) unless block
     822    size = self.size
     823    if n == 0
     824      yield []
     825    elsif 0 < n && n <= size
     826      i = 0
     827      while i<size
     828        result = [self[i]]
     829        if n-1 > 0
     830          ary = self[0...i] + self[i+1..-1]
     831          ary.permutation(n-1) do |c|
     832            yield result + c
     833          end
     834        else
     835          yield result
     836        end
     837        i += 1
     838      end
     839    end
     840    self
     841  end
     842
     843  ##
     844  # call-seq:
     845  #    ary.combination(n) { |c| block }    -> ary
     846  #    ary.combination(n)                  -> Enumerator
     847  #
     848  # When invoked with a block, yields all combinations of length +n+ of elements
     849  # from the array and then returns the array itself.
     850  #
     851  # The implementation makes no guarantees about the order in which the
     852  # combinations are yielded.
     853  #
     854  # If no block is given, an Enumerator is returned instead.
     855  #
     856  # Examples:
     857  #
     858  #    a = [1, 2, 3, 4]
     859  #    a.combination(1).to_a  #=> [[1],[2],[3],[4]]
     860  #    a.combination(2).to_a  #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
     861  #    a.combination(3).to_a  #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
     862  #    a.combination(4).to_a  #=> [[1,2,3,4]]
     863  #    a.combination(0).to_a  #=> [[]] # one combination of length 0
     864  #    a.combination(5).to_a  #=> []   # no combinations of length 5
     865
     866  def combination(n, &block)
     867    return to_enum(:combination, n) unless block
     868    size = self.size
     869    if n == 0
     870       yield []
     871    elsif n == 1
     872      i = 0
     873      while i<size
     874        yield [self[i]]
     875        i += 1
     876      end
     877    elsif n <= size
     878      i = 0
     879      while i<size
     880        result = [self[i]]
     881        self[i+1..-1].combination(n-1) do |c|
     882          yield result + c
     883        end
     884        i += 1
     885      end
     886    end
     887    self
     888  end
     889
     890  ##
     891  # call-seq:
     892  #    ary.transpose -> new_ary
     893  #
     894  # Assumes that self is an array of arrays and transposes the rows and columns.
     895  #
     896  # If the length of the subarrays don't match, an IndexError is raised.
     897  #
     898  # Examples:
     899  #
     900  #    a = [[1,2], [3,4], [5,6]]
     901  #    a.transpose   #=> [[1, 3, 5], [2, 4, 6]]
     902
     903  def transpose
     904    return [] if empty?
     905
     906    column_count = nil
     907    self.each do |row|
     908      raise TypeError unless row.is_a?(Array)
     909      column_count ||= row.size
     910      raise IndexError, 'element size differs' unless column_count == row.size
     911    end
     912
     913    Array.new(column_count) do |column_index|
     914      self.map { |row| row[column_index] }
     915    end
     916  end
     917
     918  ##
     919  #  call-seq:
     920  #    ary.to_h                ->   Hash
     921  #    ary.to_h{|item| ... }   ->   Hash
     922  #
     923  # Returns the result of interpreting <i>aray</i> as an array of
     924  # <tt>[key, value]</tt> pairs. If a block is given, it should
     925  # return <tt>[key, value]</tt> pairs to construct a hash.
     926  #
     927  #     [[:foo, :bar], [1, 2]].to_h
     928  #       # => {:foo => :bar, 1 => 2}
     929  #     [1, 2].to_h{|x| [x, x*2]}
     930  #       # => {1 => 2, 2 => 4}
     931  #
     932  def to_h(&blk)
     933    h = {}
     934    self.each do |v|
     935      v = blk.call(v) if blk
     936      raise TypeError, "wrong element type #{v.class}" unless Array === v
     937      raise ArgumentError, "wrong array length (expected 2, was #{v.length})" unless v.length == 2
     938      h[v[0]] = v[1]
     939    end
     940    h
     941  end
     942
     943  alias append push
     944  alias prepend unshift
     945  alias filter! select!
    765946end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/src/array.c

    r331 r439  
    6666  for (i = 0; i < RARRAY_LEN(ary); ++i) {
    6767    v = RARRAY_PTR(ary)[i];
    68     if (mrb_type(v) == MRB_TT_ARRAY &&
     68    if (mrb_array_p(v) &&
    6969        RARRAY_LEN(v) > 1 &&
    7070        mrb_equal(mrb, RARRAY_PTR(v)[1], value))
     
    107107}
    108108
    109 /*
    110  *  call-seq:
    111  *     ary.to_h   ->   Hash
    112  *
    113  *  Returns the result of interpreting <i>aray</i> as an array of
    114  *  <tt>[key, value]</tt> paris.
    115  *
    116  *      [[:foo, :bar], [1, 2]].to_h
    117  *        # => {:foo => :bar, 1 => 2}
    118  *
    119  */
    120 
    121 static mrb_value
    122 mrb_ary_to_h(mrb_state *mrb, mrb_value ary)
    123 {
    124   mrb_int i;
    125   mrb_value v, hash;
    126 
    127   hash = mrb_hash_new_capa(mrb, 0);
    128 
    129   for (i = 0; i < RARRAY_LEN(ary); ++i) {
    130     v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
    131 
    132     if (mrb_nil_p(v)) {
    133       mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)",
    134         mrb_str_new_cstr(mrb,  mrb_obj_classname(mrb, ary_elt(ary, i))),
    135         mrb_fixnum_value(i)
    136       );
    137     }
    138 
    139     if (RARRAY_LEN(v) != 2) {
    140       mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong array length at %S (expected 2, was %S)",
    141         mrb_fixnum_value(i),
    142         mrb_fixnum_value(RARRAY_LEN(v))
    143       );
    144     }
    145 
    146     mrb_hash_set(mrb, hash, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);
    147   }
    148 
    149   return hash;
    150 }
    151109
    152110/*
     
    175133{
    176134  struct RArray *a = mrb_ary_ptr(self);
    177   mrb_int i, j, k, len;
    178   mrb_value index;
     135  mrb_int i, j, k, len, alen;
    179136  mrb_value val;
    180137  mrb_value *ptr;
     
    183140  mrb_ary_modify(mrb, a);
    184141
    185   if (mrb_get_args(mrb, "o|i", &index, &len) == 1) {
     142  if (mrb_get_argc(mrb) == 1) {
     143    mrb_value index;
     144
     145    mrb_get_args(mrb, "o|i", &index, &len);
    186146    switch (mrb_type(index)) {
    187147    case MRB_TT_RANGE:
    188       if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
     148      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
    189149        goto delete_pos_len;
    190150      }
     
    201161  }
    202162
    203   i = mrb_fixnum(index);
     163  mrb_get_args(mrb, "ii", &i, &len);
    204164 delete_pos_len:
    205   if (i < 0) i += a->len;
    206   if (i < 0 || a->len < i) return mrb_nil_value();
     165  alen = ARY_LEN(a);
     166  if (i < 0) i += alen;
     167  if (i < 0 || alen < i) return mrb_nil_value();
    207168  if (len < 0) return mrb_nil_value();
    208   if (a->len == i) return mrb_ary_new(mrb);
    209   if (len > a->len - i) len = a->len - i;
     169  if (alen == i) return mrb_ary_new(mrb);
     170  if (len > alen - i) len = alen - i;
    210171
    211172  ary = mrb_ary_new_capa(mrb, len);
    212 
     173  ptr = ARY_PTR(a);
    213174  for (j = i, k = 0; k < len; ++j, ++k) {
    214     mrb_ary_push(mrb, ary, a->ptr[j]);
    215   }
    216 
    217   ptr = a->ptr + i;
    218   for (j = i; j < a->len - len; ++j) {
     175    mrb_ary_push(mrb, ary, ptr[j]);
     176  }
     177
     178  ptr += i;
     179  for (j = i; j < alen - len; ++j) {
    219180    *ptr = *(ptr+len);
    220181    ++ptr;
    221182  }
    222183
    223   mrb_ary_resize(mrb, self, a->len - len);
     184  mrb_ary_resize(mrb, self, alen - len);
    224185  return ary;
    225186}
     
    234195  mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1));
    235196  mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY());
    236   mrb_define_method(mrb, a, "to_h",   mrb_ary_to_h, MRB_ARGS_REQ(0));
    237   mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang,   MRB_ARGS_ANY());
     197  mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang,   MRB_ARGS_ARG(1,1));
    238198}
    239199
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/test/array.rb

    r331 r439  
    22# Array(Ext) Test
    33
    4 assert("Array.try_convert") do
    5   assert_nil Array.try_convert(0)
    6   assert_nil Array.try_convert(nil)
    7   assert_equal [], Array.try_convert([])
    8   assert_equal [1,2,3], Array.try_convert([1,2,3])
     4def assert_permutation_combination(exp, receiver, meth, *args)
     5  act = []
     6  ret = receiver.__send__(meth, *args) { |v| act << v }
     7  assert "assert_#{meth}" do
     8    assert_equal(exp, act.sort)
     9    assert_same(receiver, ret)
     10  end
     11end
     12
     13def assert_permutation(exp, receiver, *args)
     14  assert_permutation_combination(exp, receiver, :permutation, *args)
     15end
     16
     17def assert_combination(exp, receiver, *args)
     18  assert_permutation_combination(exp, receiver, :combination, *args)
    919end
    1020
     
    7686end
    7787
     88assert("Array#union") do
     89  a = [1, 2, 3, 1]
     90  b = [1, 4]
     91  c = [1, 5]
     92
     93  assert_equal [1, 2, 3, 4, 5], a.union(b,c)
     94end
     95
     96assert("Array#difference") do
     97  a = [1, 2, 3, 1, 6, 7]
     98  b = [1, 4, 6]
     99  c = [1, 5, 7]
     100
     101  assert_equal [2, 3], a.difference(b,c)
     102end
     103
    78104assert("Array#&") do
    79105  a = [1, 2, 3, 1]
     
    84110  assert_equal [1], (a & b)
    85111  assert_equal [1, 2, 3, 1], a
     112end
     113
     114assert("Array#intersection") do
     115  a = [1, 2, 3, 1, 8, 6, 7, 8]
     116  b = [1, 4, 6, 8]
     117  c = [1, 5, 7, 8]
     118
     119  assert_equal [1, 8], a.intersection(b,c)
    86120end
    87121
     
    162196  end
    163197  assert_equal [ "d", "c", "b", "a" ], b
    164 
    165   if Object.const_defined?(:Enumerator)
    166     assert_equal [ "d", "c", "b", "a" ], a.reverse_each.to_a
    167   else
    168     true
    169   end
    170198end
    171199
     
    229257assert("Array#bsearch") do
    230258  # Find minimum mode
    231   a = [0, 4, 7, 10, 12]
    232   assert_include [4, 7], a.bsearch {|x| x >= 4 }
    233   assert_equal 7, a.bsearch {|x| x >= 6 }
    234   assert_equal 0, a.bsearch {|x| x >= -1 }
    235   assert_nil a.bsearch {|x| x >= 100 }
     259  a = [0, 2, 4]
     260  assert_equal 0, a.bsearch{ |x| x >= -1 }
     261  assert_equal 0, a.bsearch{ |x| x >= 0 }
     262  assert_equal 2, a.bsearch{ |x| x >= 1 }
     263  assert_equal 2, a.bsearch{ |x| x >= 2 }
     264  assert_equal 4, a.bsearch{ |x| x >= 3 }
     265  assert_equal 4, a.bsearch{ |x| x >= 4 }
     266  assert_nil      a.bsearch{ |x| x >= 5 }
    236267
    237268  # Find any mode
    238   a = [0, 4, 7, 10, 12]
    239   assert_include [4, 7], a.bsearch {|x| 1 - (x / 4).truncate }
    240   assert_nil a.bsearch {|x| 4 - (x / 2).truncate }
    241   assert_equal(nil, a.bsearch {|x| 1 })
    242   assert_equal(nil, a.bsearch {|x| -1 })
    243 end
    244 
    245 assert("Array#delete_if") do
    246   a = [1, 2, 3, 4, 5]
    247   assert_equal [1, 2, 3, 4, 5], a.delete_if { false }
    248   assert_equal [1, 2, 3, 4, 5], a
    249 
    250   a = [1, 2, 3, 4, 5]
    251   assert_equal [], a.delete_if { true }
    252   assert_equal [], a
    253 
    254   a = [ 1, 2, 3, 4, 5 ]
    255   assert_equal [1, 2, 3], a.delete_if { |val| val > 3 }
    256 end
     269  a = [0, 4, 8]
     270  def between(lo, x, hi)
     271    if x < lo
     272      1
     273    elsif x > hi
     274      -1
     275    else
     276      0
     277    end
     278  end
     279  assert_nil      a.bsearch{ |x| between(-3, x, -1) }
     280  assert_equal 0, a.bsearch{ |x| between(-1, x,  1) }
     281  assert_nil      a.bsearch{ |x| between( 1, x,  3) }
     282  assert_equal 4, a.bsearch{ |x| between( 3, x,  5) }
     283  assert_nil      a.bsearch{ |x| between( 5, x,  7) }
     284  assert_equal 8, a.bsearch{ |x| between( 7, x,  9) }
     285  assert_nil      a.bsearch{ |x| between( 9, x, 11) }
     286
     287  assert_equal 0, a.bsearch{ |x| between( 0, x,  3) }
     288  assert_equal 4, a.bsearch{ |x| between( 0, x,  4) }
     289  assert_equal 4, a.bsearch{ |x| between( 4, x,  8) }
     290  assert_equal 8, a.bsearch{ |x| between( 5, x,  8) }
     291
     292  # Invalid block result
     293  assert_raise TypeError, 'invalid block result (must be numeric, true, false or nil)' do
     294    a.bsearch{ 'I like to watch the world burn' }
     295  end
     296end
     297
     298# tested through Array#bsearch
     299#assert("Array#bsearch_index") do
     300#end
    257301
    258302assert("Array#keep_if") do
     
    302346end
    303347
    304 assert('Array#to_h (Modified)') do
    305   class A
    306     def to_ary
    307       $a.clear
    308       nil
    309     end
    310   end
    311   $a = [A.new]
    312   assert_raise(TypeError) { $a.to_h }
    313 end
    314 
    315348assert("Array#index (block)") do
    316349  assert_nil (1..10).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
    317350  assert_equal 34, (1..100).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
    318 end
    319 
    320 assert("Array#to_ary") do
    321   assert_equal [], [].to_ary
    322   assert_equal [1,2,3], [1,2,3].to_ary
    323351end
    324352
     
    353381  assert_equal(j, nil)
    354382end
     383
     384assert("Array#permutation") do
     385  a = [1, 2, 3]
     386  assert_permutation([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]], a)
     387  assert_permutation([[1],[2],[3]], a, 1)
     388  assert_permutation([[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]], a, 2)
     389  assert_permutation([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]], a, 3)
     390  assert_permutation([[]], a, 0)
     391  assert_permutation([], a, 4)
     392  assert_permutation([], a, -1)
     393end
     394
     395assert("Array#combination") do
     396  a = [1, 2, 3, 4]
     397  assert_combination([[1],[2],[3],[4]], a, 1)
     398  assert_combination([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], a, 2)
     399  assert_combination([[1,2,3],[1,2,4],[1,3,4],[2,3,4]], a, 3)
     400  assert_combination([[1,2,3,4]], a, 4)
     401  assert_combination([[]], a, 0)
     402  assert_combination([], a, 5)
     403  assert_combination([], a, -1)
     404end
     405
     406assert('Array#transpose') do
     407  assert_equal([].transpose, [])
     408  assert_equal([[]].transpose, [])
     409  assert_equal([[1]].transpose, [[1]])
     410  assert_equal([[1,2,3]].transpose, [[1], [2], [3]])
     411  assert_equal([[1], [2], [3]].transpose, [[1,2,3]])
     412  assert_equal([[1,2], [3,4], [5,6]].transpose, [[1,3,5], [2,4,6]])
     413  assert_raise(TypeError) { [1].transpose }
     414  assert_raise(IndexError) { [[1], [2,3,4]].transpose }
     415end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/bintest/print.rb

    r331 r439  
    11require 'open3'
    22require 'tempfile'
     3require 'strscan'
    34
    45class BinTest_MrubyBinDebugger
    5   @debug1=false
    6   @debug2=true
     6#  @debug1=false
     7#  @debug2=true
    78  def self.test(rubysource, testcase)
    89    script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb'])
     
    2021    stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n"
    2122
     23    prompt = /^\(#{Regexp.escape(script.path)}:\d+\) /
    2224    ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd|
    2325      o, s = Open3.capture2(cmd, :stdin_data => stdin_data)
    24 
    25       exp_vals = testcase.map{|t| t.fetch(:exp, nil)}
     26      scanner = StringScanner.new(o)
     27      scanner.skip_until(prompt)
     28      testcase.each do |tc|
     29        exp = tc[:exp]
     30        if exp
     31          act = scanner.scan_until(/\n/)
     32          break unless assert_operator act, :start_with?, exp
     33        end
     34        scanner.skip_until(prompt)
     35      end
     36
    2637=begin
    2738if @debug1
     
    4253      end
    4354=end
    44       idx = 0
    45       exp_vals.each do |exp|
    46         next if exp.nil?
    47         idx = o.index(exp, idx)
    48         assert_false idx.nil?
    49         break unless idx
    50         idx += 1
    51       end
    5255    end
    5356  end
     
    9194  # test case
    9295  tc = []
    93   tc << {:cmd=>"p (1+2",  :exp=>'$1 = SyntaxError'}
    94   tc << {:cmd=>"p bar",   :exp=>'$2 = NoMethodError'}
     96  tc << {:cmd=>"p (1+2",  :exp=>'$1 = line 1: syntax error'}
     97  tc << {:cmd=>"p bar",   :exp=>'$2 = undefined method'}
    9598
    9699  BinTest_MrubyBinDebugger.test(src, tc)
     
    318321SRC
    319322
    320   # todo: wait for 'break' to be implimented
     323  # todo: wait for 'break' to be implemented
    321324  tc = []
    322325  9.times { tc << {:cmd=>"s"} }
     
    342345  tc << {:cmd=>"p 0x100",   :exp=>'$4 = 256'}
    343346  tc << {:cmd=>"p 1_234",   :exp=>'$5 = 1234'}
    344   tc << {:cmd=>"p 0b1000_0000", :exp=>"$6 = #{0b1000_0000.to_s}"}
    345   tc << {:cmd=>"p 0x1000_0000", :exp=>"$7 = #{0x1000_0000.to_s}"}
     347  tc << {:cmd=>"p 0b1000_0000", :exp=>"$6 = #{0b1000_0000}"}
     348  tc << {:cmd=>"p 0x1000_0000", :exp=>"$7 = #{0x1000_0000}"}
    346349
    347350  tc << {:cmd=>"p 3.14",    :exp=>'$8 = 3.14'}
    348351  tc << {:cmd=>"p -12.3",   :exp=>'$9 = -12.3'}
    349   tc << {:cmd=>"p +12.000", :exp=>'$10 = 12.0'}
    350   tc << {:cmd=>"p 1e4",     :exp=>'$11 = 10000.0'}
     352  tc << {:cmd=>"p +12.000", :exp=>'$10 = 12'}
     353  tc << {:cmd=>"p 1e4",     :exp=>'$11 = 10000'}
    351354  tc << {:cmd=>"p -0.1e-2", :exp=>'$12 = -0.001'}
    352355
     
    369372  tc << {:cmd=>'p "str"',        :exp=>'$1 = "str"'}
    370373  tc << {:cmd=>'p "s\tt\rr\n"',  :exp=>'$2 = "s\\tt\\rr\\n"'}
    371   tc << {:cmd=>'p "\C-a\C-z"',   :exp=>'$3 = "\\001\\032"'}
     374  tc << {:cmd=>'p "\C-a\C-z"',   :exp=>'$3 = "\\x01\\x1a"'}
    372375  tc << {:cmd=>'p "#{foo+bar}"', :exp=>'$4 = "foobar"'}
    373376
     
    375378  tc << {:cmd=>'p \'s\\tt\\rr\\n\'', :exp=>'$6 = "s\\\\tt\\\\rr\\\\n"'}
    376379  tc << {:cmd=>'p \'\\C-a\\C-z\'',   :exp=>'$7 = "\\\\C-a\\\\C-z"'}
    377   tc << {:cmd=>'p \'#{foo+bar}\'',   :exp=>'$8 = "#{foo+bar}"'}
     380  tc << {:cmd=>'p \'#{foo+bar}\'',   :exp=>'$8 = "\\#{foo+bar}"'}
    378381
    379382  tc << {:cmd=>'p %!str!',        :exp=>'$9 = "str"'}
    380383  tc << {:cmd=>'p %!s\tt\rr\n!',  :exp=>'$10 = "s\\tt\\rr\\n"'}
    381   tc << {:cmd=>'p %!\C-a\C-z!',   :exp=>'$11 = "\\001\\032"'}
     384  tc << {:cmd=>'p %!\C-a\C-z!',   :exp=>'$11 = "\\x01\\x1a"'}
    382385  tc << {:cmd=>'p %!#{foo+bar}!', :exp=>'$12 = "foobar"'}
    383386
    384387  tc << {:cmd=>'p %Q!str!',        :exp=>'$13 = "str"'}
    385388  tc << {:cmd=>'p %Q!s\tt\rr\n!',  :exp=>'$14 = "s\\tt\\rr\\n"'}
    386   tc << {:cmd=>'p %Q!\C-a\C-z!',   :exp=>'$15 = "\\001\\032"'}
     389  tc << {:cmd=>'p %Q!\C-a\C-z!',   :exp=>'$15 = "\\x01\\x1a"'}
    387390  tc << {:cmd=>'p %Q!#{foo+bar}!', :exp=>'$16 = "foobar"'}
    388391
     
    390393  tc << {:cmd=>'p %q!s\\tt\\rr\\n!', :exp=>'$18 = "s\\\\tt\\\\rr\\\\n"'}
    391394  tc << {:cmd=>'p %q!\\C-a\\C-z!',   :exp=>'$19 = "\\\\C-a\\\\C-z"'}
    392   tc << {:cmd=>'p %q!#{foo+bar}!',   :exp=>'$20 = "#{foo+bar}"'}
     395  tc << {:cmd=>'p %q!#{foo+bar}!',   :exp=>'$20 = "\\#{foo+bar}"'}
    393396
    394397  BinTest_MrubyBinDebugger.test(src, tc)
     
    411414  tc << {:cmd=>'p [ 5,  12,   8,    10, ]', :exp=>'$2 = [5, 12, 8, 10]'}
    412415  tc << {:cmd=>'p [1,2.5,"#{foo+bar}"]',    :exp=>'$3 = [1, 2.5, "foobar"]'}
    413   tc << {:cmd=>'p %w[3.14 A\ &\ B #{foo}]', :exp=>'$4 = ["3.14", "A & B", "#{foo}"]'}
     416  tc << {:cmd=>'p %w[3.14 A\ &\ B #{foo}]', :exp=>'$4 = ["3.14", "A & B", "\#{foo}"]'}
    414417  tc << {:cmd=>'p %W[3.14 A\ &\ B #{foo}]', :exp=>'$5 = ["3.14", "A & B", "foo"]'}
    415418
     
    589592
    590593  tc << {:cmd=>'p undefined=-1',      :exp=>'$3 = -1'}
    591   tc << {:cmd=>'p "#{undefined}"',    :exp=>'$4 = NoMethodError'}
     594  tc << {:cmd=>'p "#{undefined}"',    :exp=>'$4 = undefined method'}
    592595
    593596  BinTest_MrubyBinDebugger.test(src, tc)
     
    627630
    628631  tc << {:cmd=>'p undefined=-1',    :exp=>'$14 = -1'}
    629   tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = NoMethodError'}
     632  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = undefined method'}
    630633
    631634  BinTest_MrubyBinDebugger.test(src, tc)
     
    695698
    696699  tc << {:cmd=>'p undefined=-1',    :exp=>'$14 = -1'}
    697   tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = NoMethodError'}
    698 
    699   BinTest_MrubyBinDebugger.test(src, tc)
    700 end
    701 
     700  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = undefined method'}
     701
     702  BinTest_MrubyBinDebugger.test(src, tc)
     703end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c

    r331 r439  
    8585
    8686static uint16_t
    87 check_file_lineno(struct mrb_irep *irep, const char *file, uint16_t lineno)
     87check_file_lineno(mrb_state *mrb, struct mrb_irep *irep, const char *file, uint16_t lineno)
    8888{
    8989  mrb_irep_debug_info_file *info_file;
     
    9494
    9595  for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
     96    const char *filename;
    9697    info_file = irep->debug_info->files[f_idx];
    97     if (!strcmp(info_file->filename, file)) {
     98    filename = mrb_sym_name_len(mrb, info_file->filename_sym, NULL);
     99    if (!strcmp(filename, file)) {
    98100      result = MRB_DEBUG_BP_FILE_OK;
    99101
     
    104106    }
    105107    for (i=0; i < irep->rlen; ++i) {
    106       result  |= check_file_lineno(irep->reps[i], file, lineno);
     108      result  |= check_file_lineno(mrb, irep->reps[i], file, lineno);
    107109      if (result == (MRB_DEBUG_BP_FILE_OK | MRB_DEBUG_BP_LINENO_OK)) {
    108110        return result;
     
    113115}
    114116
    115 static const char*
    116 get_class_name(mrb_state *mrb, struct RClass *class_obj)
    117 {
    118   struct RClass *outer;
    119   mrb_sym class_sym;
    120 
    121   outer = mrb_class_outer_module(mrb, class_obj);
    122   class_sym = mrb_class_sym(mrb, class_obj, outer);
    123   return mrb_sym2name(mrb, class_sym);
    124 }
    125 
    126117static int32_t
    127118compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc)
     
    129120  const char* class_name;
    130121  const char* method_name;
    131   struct RProc* m;
     122  mrb_method_t m;
    132123  struct RClass* sc;
    133124  const char* sn;
     
    136127  mrb_bool is_defined;
    137128
    138   method_name = mrb_sym2name(mrb, method_sym);
     129  method_name = mrb_sym_name(mrb, method_sym);
    139130
    140131  method_p = &bp->point.methodpoint;
    141132  if (strcmp(method_p->method_name, method_name) == 0) {
    142     class_name = get_class_name(mrb, class_obj);
     133    class_name = mrb_class_name(mrb, class_obj);
    143134    if (class_name == NULL) {
    144135      if (method_p->class_name == NULL) {
     
    148139    else if (method_p->class_name != NULL) {
    149140      m = mrb_method_search_vm(mrb, &class_obj, method_sym);
    150       if (m == NULL) {
     141      if (MRB_METHOD_UNDEF_P(m)) {
    151142        return MRB_DEBUG_OK;
    152143      }
    153       if (MRB_PROC_CFUNC_P(m)) {
     144      if (MRB_METHOD_CFUNC_P(m)) {
    154145        *isCfunc = TRUE;
    155146      }
     
    163154      ssym = mrb_symbol(mrb_check_intern_cstr(mrb, method_p->method_name));
    164155      m = mrb_method_search_vm(mrb, &sc, ssym);
    165       if (m == NULL) {
     156      if (MRB_METHOD_UNDEF_P(m)) {
    166157        return MRB_DEBUG_OK;
    167158      }
    168159
    169       class_name = get_class_name(mrb, class_obj);
    170       sn = get_class_name(mrb, sc);
     160      class_name = mrb_class_name(mrb, class_obj);
     161      sn = mrb_class_name(mrb, sc);
    171162      if (strcmp(sn, class_name) == 0) {
    172163        return bp->bpno;
     
    197188
    198189  /* file and lineno check (line type mrb_debug_line_ary only.) */
    199   result = check_file_lineno(dbg->root_irep, file, lineno);
     190  result = check_file_lineno(mrb, dbg->root_irep, file, lineno);
    200191  if (result == 0) {
    201192    return MRB_DEBUG_BREAK_INVALID_FILE;
     
    205196  }
    206197
    207   set_file = mrb_malloc(mrb, strlen(file) + 1);
     198  set_file = (char*)mrb_malloc(mrb, strlen(file) + 1);
    208199
    209200  index = dbg->bpnum;
     
    242233
    243234  if (class_name != NULL) {
    244     set_class = mrb_malloc(mrb, strlen(class_name) + 1);
     235    set_class = (char*)mrb_malloc(mrb, strlen(class_name) + 1);
    245236    strncpy(set_class, class_name, strlen(class_name) + 1);
    246237  }
     
    249240  }
    250241
    251   set_method = mrb_malloc(mrb, strlen(method_name) + 1);
     242  set_method = (char*)mrb_malloc(mrb, strlen(method_name) + 1);
    252243
    253244  strncpy(set_method, method_name, strlen(method_name) + 1);
     
    438429
    439430static mrb_bool
    440 check_start_pc_for_line(mrb_irep *irep, mrb_code *pc, uint16_t line)
     431check_start_pc_for_line(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, uint16_t line)
    441432{
    442433  if (pc > irep->iseq) {
    443     if (line == mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq - 1))) {
     434    if (line == mrb_debug_get_line(mrb, irep, pc - irep->iseq - 1)) {
    444435      return FALSE;
    445436    }
     
    459450  }
    460451
    461   if (!check_start_pc_for_line(dbg->irep, dbg->pc, line)) {
     452  if (!check_start_pc_for_line(mrb, dbg->irep, dbg->pc, line)) {
    462453    return MRB_DEBUG_OK;
    463454  }
     
    515506  return 0;
    516507}
    517 
    518 
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c

    r331 r439  
    4949  }
    5050
    51   path = mrb_malloc(mrb, len);
     51  path = (char*)mrb_malloc(mrb, len);
    5252  memset(path, 0, len);
    5353
     
    6565{
    6666  size_t len;
    67   char *p, *dir;
     67  const char *p;
     68  char *dir;
    6869
    6970  if (path == NULL) {
     
    7475  len = p != NULL ? (size_t)(p - path) : strlen(path);
    7576
    76   dir = mrb_malloc(mrb, len + 1);
     77  dir = (char*)mrb_malloc(mrb, len + 1);
    7778  strncpy(dir, path, len);
    7879  dir[len] = '\0';
     
    8485source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename)
    8586{
    86   source_file *file = NULL;
    87 
    88   file = mrb_malloc(mrb, sizeof(source_file));
     87  source_file *file;
     88
     89  file = (source_file*)mrb_malloc(mrb, sizeof(source_file));
    8990
    9091  memset(file, '\0', sizeof(source_file));
     
    9798
    9899  file->lineno = 1;
    99   file->path = mrb_malloc(mrb, strlen(filename) + 1);
     100  file->path = (char*)mrb_malloc(mrb, strlen(filename) + 1);
    100101  strcpy(file->path, filename);
    101102  return file;
     
    175176  const char *search_path[3];
    176177  char *path = NULL;
     178  const char *srcname = strrchr(filename, '/');
     179
     180  if (srcname) srcname++;
     181  else srcname = filename;
    177182
    178183  search_path[0] = srcpath;
    179   search_path[1] = dirname(mrb, mrb_debug_get_filename(mrdb->dbg->root_irep, 0));
     184  search_path[1] = dirname(mrb, mrb_debug_get_filename(mrb, mrdb->dbg->irep, 0));
    180185  search_path[2] = ".";
    181186
     
    185190    }
    186191
    187     if ((path = build_path(mrb, search_path[i], filename)) == NULL) {
     192    if ((path = build_path(mrb, search_path[i], srcname)) == NULL) {
    188193      continue;
    189194    }
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c

    r331 r439  
    2222  c->no_exec = TRUE;
    2323  c->capture_errors = TRUE;
    24   c->filename = (char*)dbg->prvfile;
     24  mrbc_filename(mrb, c, (const char*)dbg->prvfile);
    2525  c->lineno = dbg->prvline;
    2626
     
    3232
    3333mrb_value
    34 mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc)
     34mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval)
    3535{
    36   void (*tmp)(struct mrb_state *, struct mrb_irep *, mrb_code *, mrb_value *);
     36  void (*tmp)(struct mrb_state *, struct mrb_irep *, const mrb_code *, mrb_value *);
    3737  mrb_value ruby_code;
    3838  mrb_value s;
     
    4848    v = mrb_obj_value(mrb->exc);
    4949    mrb->exc = 0;
     50  }
     51  else if (direct_eval) {
     52    recv = dbg->regs[0];
     53
     54    v = mrb_funcall(mrb, recv, expr, 0);
    5055  }
    5156  else {
     
    7075  }
    7176
    72   s = mrb_funcall(mrb, v, "inspect", 0);
     77  s = mrb_inspect(mrb, v);
    7378
    7479  /* enable code_fetch_hook */
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h

    r331 r439  
    99#include "mrdb.h"
    1010
    11 mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool*);
     11mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool*, int);
    1212
    1313#endif /* APIPRINT_H_ */
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c

    r331 r439  
    243243
    244244mrb_debug_bptype
    245 parse_breakcommand(mrdb_state *mrdb, const char **file, uint32_t *line, char **cname, char **method)
     245parse_breakcommand(mrb_state *mrb, mrdb_state *mrdb, const char **file, uint32_t *line, char **cname, char **method)
    246246{
    247247  mrb_debug_context *dbg = mrdb->dbg;
     
    275275      if (l <= 65535) {
    276276        *line = l;
    277         *file = (body == args)? mrb_debug_get_filename(dbg->irep, (uint32_t)(dbg->pc - dbg->irep->iseq)): args;
     277        *file = (body == args)? mrb_debug_get_filename(mrb, dbg->irep, dbg->pc - dbg->irep->iseq): args;
    278278      }
    279279      else {
     
    333333  int32_t ret;
    334334
    335   type = parse_breakcommand(mrdb, &file, &line, &cname, &method);
     335  type = parse_breakcommand(mrb, mrdb, &file, &line, &cname, &method);
    336336  switch (type) {
    337337    case MRB_DEBUG_BPTYPE_LINE:
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c

    r331 r439  
    8181    "Status of specified breakpoints (all user-settable breakpoints if no argument).\n"
    8282    "Arguments are breakpoint numbers with spaces in between.\n"
     83  },
     84  {
     85    "i[nfo]", "l[ocals]", "Print name of local variables",
     86    "Usage: info locals\n"
     87    "\n"
     88    "Print name of local variables.\n"
    8389  },
    8490  {
     
    134140listcmd_parser_state_new(mrb_state *mrb)
    135141{
    136   listcmd_parser_state *st = mrb_malloc(mrb, sizeof(listcmd_parser_state));
     142  listcmd_parser_state *st = (listcmd_parser_state*)mrb_malloc(mrb, sizeof(listcmd_parser_state));
    137143  memset(st, 0, sizeof(listcmd_parser_state));
    138144  return st;
     
    228234
    229235  if (len > 0) {
    230     st->filename = mrb_malloc(mrb, len + 1);
     236    st->filename = (char*)mrb_malloc(mrb, len + 1);
    231237    strncpy(st->filename, *sp, len);
    232238    st->filename[len] = '\0';
     
    243249{
    244250  size_t len;
    245   char *p, *s;
     251  const char *p;
     252  char *s;
    246253
    247254  if (filename == NULL) {
     
    256263  }
    257264
    258   s = mrb_malloc(mrb, len + strlen(ext) + 1);
     265  s = (char*)mrb_malloc(mrb, len + strlen(ext) + 1);
    259266  memset(s, '\0', len + strlen(ext) + 1);
    260267  strncpy(s, filename, len);
     
    326333check_cmd_pattern(const char *pattern, const char *cmd)
    327334{
    328   char *lbracket, *rbracket, *p, *q;
     335  const char *lbracket, *rbracket, *p, *q;
    329336
    330337  if (pattern == NULL && cmd == NULL) {
     
    495502  if (mrdb->dbg->xm == DBG_QUIT) {
    496503    struct RClass *exc;
    497     exc = mrb_define_class(mrb, "DebuggerExit", mrb_class_get(mrb, "Exception"));
     504    exc = mrb_define_class(mrb, "DebuggerExit", mrb->eException_class);
    498505    mrb_raise(mrb, exc, "Exit mrdb.");
    499506  }
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c

    r331 r439  
    1919  mrb_value expr;
    2020  mrb_value result;
    21   mrb_value s;
    2221  uint8_t wcnt;
    2322  int ai;
     
    3736  }
    3837
    39   result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL);
     38  result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL, 0);
    4039
    4140  /* $print_no = result */
    42   s = mrb_str_cat_lit(mrb, result, "\0");
    43   printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s));
     41  printf("$%lu = ", (unsigned long)mrdb->print_no++);
     42  fwrite(RSTRING_PTR(result), RSTRING_LEN(result), 1, stdout);
     43  putc('\n', stdout);
    4444
    4545  if (mrdb->print_no == 0) {
     
    5757  return dbgcmd_print(mrb, mrdb);
    5858}
     59
     60dbgcmd_state
     61dbgcmd_info_local(mrb_state *mrb, mrdb_state *mrdb)
     62{
     63  mrb_value result;
     64  mrb_value s;
     65  int ai;
     66
     67  ai = mrb_gc_arena_save(mrb);
     68
     69  result = mrb_debug_eval(mrb, mrdb->dbg, "local_variables", 0, NULL, 1);
     70
     71  s = mrb_str_cat_lit(mrb, result, "\0");
     72  printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s));
     73
     74  if (mrdb->print_no == 0) {
     75    mrdb->print_no = 1;
     76  }
     77
     78  mrb_gc_arena_restore(mrb, ai);
     79
     80  return DBGST_PROMPT;
     81}
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c

    r331 r439  
    2020      struct RClass *exc;
    2121      puts("Start it from the beginning.");
    22       exc = mrb_define_class(mrb, "DebuggerRestart", mrb_class_get(mrb, "Exception"));
     22      exc = mrb_define_class(mrb, "DebuggerRestart", mrb->eException_class);
    2323      mrb_raise(mrb, exc, "Restart mrdb.");
    2424    }
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c

    r331 r439  
    66#include <stdlib.h>
    77#include <string.h>
    8 #include <stdio.h>
    98#include <ctype.h>
    109
     
    5352  {"help",      NULL,           1, 0, 1, DBGCMD_HELP,           dbgcmd_help},            /* h[elp] */
    5453  {"info",      "breakpoints",  1, 1, 1, DBGCMD_INFO_BREAK,     dbgcmd_info_break},      /* i[nfo] b[reakpoints] */
     54  {"info",      "locals",       1, 1, 0, DBGCMD_INFO_LOCAL,     dbgcmd_info_local},      /* i[nfo] l[ocals] */
    5555  {"list",      NULL,           1, 0, 1, DBGCMD_LIST,           dbgcmd_list},            /* l[ist] */
    5656  {"print",     NULL,           1, 0, 0, DBGCMD_PRINT,          dbgcmd_print},           /* p[rint] */
     
    185185mrb_debug_context_new(mrb_state *mrb)
    186186{
    187   mrb_debug_context *dbg = mrb_malloc(mrb, sizeof(mrb_debug_context));
     187  mrb_debug_context *dbg = (mrb_debug_context*)mrb_malloc(mrb, sizeof(mrb_debug_context));
    188188
    189189  memset(dbg, 0, sizeof(mrb_debug_context));
     
    224224mrdb_state_new(mrb_state *mrb)
    225225{
    226   mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrdb_state));
     226  mrdb_state *mrdb = (mrdb_state*)mrb_malloc(mrb, sizeof(mrdb_state));
    227227
    228228  memset(mrdb, 0, sizeof(mrdb_state));
    229229
    230230  mrdb->dbg = mrb_debug_context_get(mrb);
    231   mrdb->command = mrb_malloc(mrb, MAX_COMMAND_LINE+1);
     231  mrdb->command = (char*)mrb_malloc(mrb, MAX_COMMAND_LINE+1);
    232232  mrdb->print_no = 1;
    233233
     
    505505
    506506static int32_t
    507 check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)
     507check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
    508508{
    509509  struct RClass* c;
     
    511511  int32_t bpno;
    512512  mrb_bool isCfunc;
     513  struct mrb_insn_data insn;
    513514
    514515  mrb_debug_context *dbg = mrb_debug_context_get(mrb);
     
    518519  dbg->method_bpno = 0;
    519520
    520   switch(GET_OPCODE(*pc)) {
     521  insn = mrb_decode_insn(pc);
     522  switch(insn.insn) {
    521523    case OP_SEND:
    522524    case OP_SENDB:
    523       c = mrb_class(mrb, regs[GETARG_A(*pc)]);
    524       sym = irep->syms[GETARG_B(*pc)];
     525      c = mrb_class(mrb, regs[insn.a]);
     526      sym = irep->syms[insn.b];
    525527      break;
    526528    case OP_SUPER:
     
    544546
    545547static void
    546 mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)
     548mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
    547549{
    548550  const char *file;
     
    567569  }
    568570
    569   file = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));
    570   line = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));
     571  file = mrb_debug_get_filename(mrb, irep, pc - irep->iseq);
     572  line = mrb_debug_get_line(mrb, irep, pc - irep->iseq);
    571573
    572574  switch (dbg->xm) {
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h

    r331 r439  
    2424  DBGCMD_BREAK,
    2525  DBGCMD_INFO_BREAK,
     26  DBGCMD_INFO_LOCAL,
    2627  DBGCMD_WATCH,
    2728  DBGCMD_INFO_WATCH,
     
    105106  struct mrb_irep *root_irep;
    106107  struct mrb_irep *irep;
    107   mrb_code *pc;
     108  const mrb_code *pc;
    108109  mrb_value *regs;
    109110
     
    152153dbgcmd_state dbgcmd_break(mrb_state*, mrdb_state*);
    153154dbgcmd_state dbgcmd_info_break(mrb_state*, mrdb_state*);
     155dbgcmd_state dbgcmd_info_local(mrb_state*, mrdb_state*);
    154156dbgcmd_state dbgcmd_delete(mrb_state*, mrdb_state*);
    155157dbgcmd_state dbgcmd_enable(mrb_state*, mrdb_state*);
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h

    r321 r439  
    66#ifndef MRDBCONF_H
    77#define MRDBCONF_H
     8
     9#ifndef MRB_ENABLE_DEBUG_HOOK
     10# error mruby-bin-debugger need 'MRB_ENABLE_DEBUG_HOOK' configuration in your 'build_config.rb'
     11#endif
     12
     13#ifdef MRB_DISABLE_STDIO
     14# error mruby-bin-debugger conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
     15#endif
    816
    917/* configuration options: */
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mirb/bintest/mirb.rb

    r321 r439  
    1111  assert_true o.include?('=> 3')
    1212end
     13
     14assert('mirb -d option') do
     15  o, _ = Open3.capture2('bin/mirb', :stdin_data => "$DEBUG\n")
     16  assert_true o.include?('=> false')
     17  o, _ = Open3.capture2('bin/mirb -d', :stdin_data => "$DEBUG\n")
     18  assert_true o.include?('=> true')
     19end
     20
     21assert('mirb -r option') do
     22  lib = Tempfile.new('lib.rb')
     23  lib.write <<EOS
     24class Hoge
     25  def hoge
     26    :hoge
     27  end
     28end
     29EOS
     30  lib.flush
     31
     32  o, _ = Open3.capture2("bin/mirb -r #{lib.path}", :stdin_data => "Hoge.new.hoge\n")
     33  assert_true o.include?('=> :hoge')
     34end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c

    r331 r439  
    77*/
    88
     9#include <mruby.h>
     10
     11#ifdef MRB_DISABLE_STDIO
     12# error mruby-bin-mirb conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
     13#endif
     14
     15#include <mruby/array.h>
     16#include <mruby/proc.h>
     17#include <mruby/compile.h>
     18#include <mruby/dump.h>
     19#include <mruby/string.h>
     20#include <mruby/variable.h>
     21#include <mruby/throw.h>
     22
    923#include <stdlib.h>
    1024#include <string.h>
    11 #include <stdio.h>
    1225#include <ctype.h>
    1326
     
    2033#define MIRB_ADD_HISTORY(line) add_history(line)
    2134#define MIRB_READLINE(ch) readline(ch)
     35#if !defined(RL_READLINE_VERSION) || RL_READLINE_VERSION < 0x600
     36/* libedit & older readline do not have rl_free() */
     37#define MIRB_LINE_FREE(line) free(line)
     38#else
     39#define MIRB_LINE_FREE(line) rl_free(line)
     40#endif
    2241#define MIRB_WRITE_HISTORY(path) write_history(path)
    2342#define MIRB_READ_HISTORY(path) read_history(path)
     
    2847#define MIRB_ADD_HISTORY(line) linenoiseHistoryAdd(line)
    2948#define MIRB_READLINE(ch) linenoise(ch)
     49#define MIRB_LINE_FREE(line) linenoiseFree(line)
    3050#define MIRB_WRITE_HISTORY(path) linenoiseHistorySave(path)
    3151#define MIRB_READ_HISTORY(path) linenoiseHistoryLoad(history_path)
     
    4262#define SIGJMP_BUF jmp_buf
    4363#endif
    44 
    45 #include <mruby.h>
    46 #include <mruby/array.h>
    47 #include <mruby/proc.h>
    48 #include <mruby/compile.h>
    49 #include <mruby/string.h>
    5064
    5165#ifdef ENABLE_READLINE
     
    89103{
    90104  mrb_value val;
     105  char* msg;
    91106
    92107  val = mrb_funcall(mrb, obj, "inspect", 0);
     
    102117    val = mrb_obj_as_string(mrb, obj);
    103118  }
    104   fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
     119  msg = mrb_locale_from_utf8(RSTRING_PTR(val), (int)RSTRING_LEN(val));
     120  fwrite(msg, strlen(msg), 1, stdout);
     121  mrb_locale_free(msg);
    105122  putc('\n', stdout);
    106123}
     
    115132  /* check for heredoc */
    116133  if (parser->parsing_heredoc != NULL) return TRUE;
    117   if (parser->heredoc_end_now) {
    118     parser->heredoc_end_now = FALSE;
    119     return FALSE;
    120   }
    121134
    122135  /* check for unterminated string */
     
    210223  FILE *rfp;
    211224  mrb_bool verbose      : 1;
     225  mrb_bool debug        : 1;
    212226  int argc;
    213227  char** argv;
     228  int libc;
     229  char **libv;
    214230};
    215231
     
    219235  static const char *const usage_msg[] = {
    220236  "switches:",
     237  "-d           set $DEBUG to true (same as `mruby -d`)",
     238  "-r library   same as `mruby -r`",
    221239  "-v           print version number, then run in verbose mode",
    222240  "--verbose    run in verbose mode",
     
    227245  const char *const *p = usage_msg;
    228246
    229   printf("Usage: %s [switches]\n", name);
     247  printf("Usage: %s [switches] [programfile] [arguments]\n", name);
    230248  while (*p)
    231249    printf("  %s\n", *p++);
    232250}
    233251
     252static char *
     253dup_arg_item(mrb_state *mrb, const char *item)
     254{
     255  size_t buflen = strlen(item) + 1;
     256  char *buf = (char*)mrb_malloc(mrb, buflen);
     257  memcpy(buf, item, buflen);
     258  return buf;
     259}
     260
    234261static int
    235262parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
    236263{
     264  char **origargv = argv;
    237265  static const struct _args args_zero = { 0 };
    238266
     
    245273    item = argv[0] + 1;
    246274    switch (*item++) {
     275    case 'd':
     276      args->debug = TRUE;
     277      break;
     278    case 'r':
     279      if (!item[0]) {
     280        if (argc <= 1) {
     281          printf("%s: No library specified for -r\n", *origargv);
     282          return EXIT_FAILURE;
     283        }
     284        argc--; argv++;
     285        item = argv[0];
     286      }
     287      if (args->libc == 0) {
     288        args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
     289      }
     290      else {
     291        args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
     292      }
     293      args->libv[args->libc++] = dup_arg_item(mrb, item);
     294      break;
    247295    case 'v':
    248296      if (!args->verbose) mrb_show_version(mrb);
     
    290338    fclose(args->rfp);
    291339  mrb_free(mrb, args->argv);
     340  if (args->libc) {
     341    while (args->libc--) {
     342      mrb_free(mrb, args->libv[args->libc]);
     343    }
     344    mrb_free(mrb, args->libv);
     345  }
    292346  mrb_close(mrb);
    293347}
     
    324378
    325379  /* skip preceding spaces */
    326   while (*p && isspace((unsigned char)*p)) {
     380  while (*p && ISSPACE(*p)) {
    327381    p++;
    328382  }
     
    334388  /* skip trailing spaces */
    335389  while (*p) {
    336     if (!isspace((unsigned char)*p)) return 0;
     390    if (!ISSPACE(*p)) return 0;
    337391    p++;
    338392  }
     
    354408{
    355409  MIRB_SIGLONGJMP(ctrl_c_buf, 1);
     410}
     411#endif
     412
     413#ifndef DISABLE_MIRB_UNDERSCORE
     414void decl_lv_underscore(mrb_state *mrb, mrbc_context *cxt)
     415{
     416  struct RProc *proc;
     417  struct mrb_parser_state *parser;
     418
     419  parser = mrb_parse_string(mrb, "_=nil", cxt);
     420  if (parser == NULL) {
     421    fputs("create parser state error\n", stderr);
     422    mrb_close(mrb);
     423    exit(EXIT_FAILURE);
     424  }
     425
     426  proc = mrb_generate_code(mrb, parser);
     427  mrb_vm_run(mrb, proc, mrb_top_self(mrb), 0);
     428
     429  mrb_parser_free(parser);
    356430}
    357431#endif
     
    404478  }
    405479  mrb_define_global_const(mrb, "ARGV", ARGV);
     480  mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug));
    406481
    407482#ifdef ENABLE_READLINE
     
    420495
    421496  cxt = mrbc_context_new(mrb);
     497
     498#ifndef DISABLE_MIRB_UNDERSCORE
     499  decl_lv_underscore(mrb, cxt);
     500#endif
     501
     502  /* Load libraries */
     503  for (i = 0; i < args.libc; i++) {
     504    FILE *lfp = fopen(args.libv[i], "r");
     505    if (lfp == NULL) {
     506      printf("Cannot open library file. (%s)\n", args.libv[i]);
     507      cleanup(mrb, &args);
     508      return EXIT_FAILURE;
     509    }
     510    mrb_load_file_cxt(mrb, lfp, cxt);
     511    fclose(lfp);
     512  }
     513
    422514  cxt->capture_errors = TRUE;
    423515  cxt->lineno = 1;
     
    429521  while (TRUE) {
    430522    char *utf8;
    431 
     523    struct mrb_jmpbuf c_jmp;
     524
     525    MRB_TRY(&c_jmp);
     526    mrb->jmp = &c_jmp;
    432527    if (args.rfp) {
    433528      if (fgets(last_code_line, sizeof(last_code_line)-1, args.rfp) != NULL)
     
    490585    strcat(last_code_line, "\n");
    491586    MIRB_ADD_HISTORY(line);
    492     free(line);
    493 #endif
    494 
    495 done:
    496 
     587    MIRB_LINE_FREE(line);
     588#endif
     589
     590  done:
    497591    if (code_block_open) {
    498592      if (strlen(ruby_code)+strlen(last_code_line) > sizeof(ruby_code)-1) {
     
    529623    }
    530624    else {
     625      if (0 < parser->nwarn) {
     626        /* warning */
     627        char* msg = mrb_locale_from_utf8(parser->warn_buffer[0].message, -1);
     628        printf("line %d: %s\n", parser->warn_buffer[0].lineno, msg);
     629        mrb_locale_free(msg);
     630      }
    531631      if (0 < parser->nerr) {
    532632        /* syntax error */
    533         printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message);
     633        char* msg = mrb_locale_from_utf8(parser->error_buffer[0].message, -1);
     634        printf("line %d: %s\n", parser->error_buffer[0].lineno, msg);
     635        mrb_locale_free(msg);
    534636      }
    535637      else {
     
    544646        if (args.verbose) {
    545647          mrb_codedump_all(mrb, proc);
     648        }
     649        /* adjust stack length of toplevel environment */
     650        if (mrb->c->cibase->env) {
     651          struct REnv *e = mrb->c->cibase->env;
     652          if (e && MRB_ENV_STACK_LEN(e) < proc->body.irep->nlocals) {
     653            MRB_ENV_SET_STACK_LEN(e, proc->body.irep->nlocals);
     654          }
    546655        }
    547656        /* pass a proc for evaluation */
     
    563672          }
    564673          p(mrb, result, 1);
     674#ifndef DISABLE_MIRB_UNDERSCORE
     675          *(mrb->c->stack + 1) = result;
     676#endif
    565677        }
    566678      }
     
    571683    mrb_parser_free(parser);
    572684    cxt->lineno++;
     685    MRB_CATCH(&c_jmp) {
     686      p(mrb, mrb_obj_value(mrb->exc), 0);
     687      mrb->exc = 0;
     688    }
     689    MRB_END_EXC(&c_jmp);
    573690  }
    574691
     
    578695#endif
    579696
     697  if (args.rfp) fclose(args.rfp);
     698  mrb_free(mrb, args.argv);
     699  if (args.libv) {
     700    for (i = 0; i < args.libc; ++i) {
     701      mrb_free(mrb, args.libv[i]);
     702    }
     703    mrb_free(mrb, args.libv);
     704  }
    580705  mrbc_context_free(mrb, cxt);
    581706  mrb_close(mrb);
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mrbc/mrbgem.rake

    r321 r439  
    99  mrbc_objs = Dir.glob("#{spec.dir}/tools/mrbc/*.c").map { |f| objfile(f.pathmap("#{spec.build_dir}/tools/mrbc/%n")) }.flatten
    1010
    11   file exec => mrbc_objs + [libfile("#{build.build_dir}/lib/libmruby_core")] do |t|
     11  file exec => mrbc_objs + [build.libmruby_core_static] do |t|
    1212    build.linker.run t.name, t.prerequisites
    1313  end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c

    r331 r439  
    1 #include <stdio.h>
     1#include <mruby.h>
     2
     3#ifdef MRB_DISABLE_STDIO
     4# error mruby-bin-mrbc conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
     5#endif
     6
    27#include <stdlib.h>
    38#include <string.h>
    4 #include <mruby.h>
    59#include <mruby/compile.h>
    610#include <mruby/dump.h>
     
    1923  mrb_bool check_syntax : 1;
    2024  mrb_bool verbose      : 1;
     25  mrb_bool remove_lv    : 1;
    2126  unsigned int flags    : 4;
    2227};
     
    3439  "-e           generate little endian iseq data",
    3540  "-E           generate big endian iseq data",
     41  "--remove-lv  remove local variables",
    3642  "--verbose    run at verbose mode",
    3743  "--version    print the version",
     
    7076parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
    7177{
    72   char *outfile = NULL;
    7378  static const struct mrbc_args args_zero = { 0 };
    7479  int i;
     
    8590        if (args->outfile) {
    8691          fprintf(stderr, "%s: an output file is already specified. (%s)\n",
    87                   args->prog, outfile);
     92                  args->prog, args->outfile);
    8893          return -1;
    8994        }
     
    143148          exit(EXIT_SUCCESS);
    144149        }
     150        else if (strcmp(argv[i] + 2, "remove-lv") == 0) {
     151          args->remove_lv = TRUE;
     152          break;
     153        }
    145154        return -1;
    146155      default:
     
    179188  }
    180189  fn = args->argv[args->idx++];
    181   p->f = fopen(fn, "r");
     190  p->f = fopen(fn, "rb");
    182191  if (p->f == NULL) {
    183192    fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn);
     
    206215  else {
    207216    need_close = TRUE;
    208     if ((infile = fopen(input, "r")) == NULL) {
     217    if ((infile = fopen(input, "rb")) == NULL) {
    209218      fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input);
    210219      return mrb_nil_value();
     
    233242  mrb_irep *irep = proc->body.irep;
    234243
     244  if (args->remove_lv) {
     245    mrb_irep_remove_lv(mrb, irep);
     246  }
    235247  if (args->initname) {
    236248    n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname);
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mruby/bintest/mruby.rb

    r331 r439  
    11require 'tempfile'
     2require 'open3'
     3
     4def assert_mruby(exp_out, exp_err, exp_success, args)
     5  out, err, stat = Open3.capture3(cmd("mruby"), *args)
     6  assert "assert_mruby" do
     7    assert_operator(exp_out, :===, out, "standard output")
     8    assert_operator(exp_err, :===, err, "standard error")
     9    assert_equal(exp_success, stat.success?, "exit success?")
     10  end
     11end
    212
    313assert('regression for #1564') do
    4   o = `#{cmd('mruby')} -e #{shellquote('<<')} 2>&1`
    5   assert_include o, "-e:1:2: syntax error"
    6   o = `#{cmd('mruby')} -e #{shellquote('<<-')} 2>&1`
    7   assert_include o, "-e:1:3: syntax error"
     14  assert_mruby("", /\A-e:1:2: syntax error, .*\n\z/, false, %w[-e <<])
     15  assert_mruby("", /\A-e:1:3: syntax error, .*\n\z/, false, %w[-e <<-])
    816end
    917
     
    1321  system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}"
    1422  o = `#{cmd('mruby')} -b #{bin.path}`.strip
    15   assert_equal o, '"ok"'
     23  assert_equal '"ok"', o
    1624end
    1725
     
    3038  # one liner
    3139  assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp
     40end
     41
     42assert 'ARGV value' do
     43  assert_mruby(%{["ab", "cde"]\n}, "", true, %w[-e p(ARGV) ab cde])
     44  assert_mruby("[]\n", "", true, %w[-e p(ARGV)])
     45end
     46
     47assert('float literal') do
     48  script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb')
     49  File.write script.path, 'p [3.21, 2e308.infinite?, -2e308.infinite?]'
     50  system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}"
     51  assert_equal "[3.21, 1, -1]", `#{cmd('mruby')} -b #{bin.path}`.chomp!
    3252end
    3353
     
    5979  assert_equal 0, $?.exitstatus
    6080end
     81
     82assert('mruby -c option') do
     83  assert_mruby("Syntax OK\n", "", true, ["-c", "-e", "p 1"])
     84  assert_mruby("", /\A-e:1:7: syntax error, .*\n\z/, false, ["-c", "-e", "p 1; 1."])
     85end
     86
     87assert('mruby -d option') do
     88  assert_mruby("false\n", "", true, ["-e", "p $DEBUG"])
     89  assert_mruby("true\n", "", true, ["-dep $DEBUG"])
     90end
     91
     92assert('mruby -e option (no code specified)') do
     93  assert_mruby("", /\A.*: No code specified for -e\n\z/, false, %w[-e])
     94end
     95
     96assert('mruby -h option') do
     97  assert_mruby(/\AUsage: #{Regexp.escape cmd("mruby")} .*/m, "", true, %w[-h])
     98end
     99
     100assert('mruby -r option') do
     101  lib = Tempfile.new('lib.rb')
     102  lib.write <<EOS
     103class Hoge
     104  def hoge
     105    :hoge
     106  end
     107end
     108EOS
     109  lib.flush
     110
     111  script = Tempfile.new('test.rb')
     112  script.write <<EOS
     113print Hoge.new.hoge
     114EOS
     115  script.flush
     116  assert_equal 'hoge', `#{cmd('mruby')} -r #{lib.path} #{script.path}`
     117  assert_equal 0, $?.exitstatus
     118
     119  assert_equal 'hogeClass', `#{cmd('mruby')} -r #{lib.path} -r #{script.path} -e #{shellquote('print Hoge.class')}`
     120  assert_equal 0, $?.exitstatus
     121end
     122
     123assert('mruby -r option (no library specified)') do
     124  assert_mruby("", /\A.*: No library specified for -r\n\z/, false, %w[-r])
     125end
     126
     127assert('mruby -r option (file not found)') do
     128  assert_mruby("", /\A.*: Cannot open library file: .*\n\z/, false, %w[-r _no_exists_])
     129end
     130
     131assert('mruby -v option') do
     132  ver_re = '\Amruby \d+\.\d+\.\d+ \(\d+-\d+-\d+\)\n'
     133  assert_mruby(/#{ver_re}\z/, "", true, %w[-v])
     134  assert_mruby(/#{ver_re}^[^\n]*NODE.*\n:end\n\z/m, "", true, %w[-v -e p(:end)])
     135end
     136
     137assert('mruby --verbose option') do
     138  assert_mruby(/\A[^\n]*NODE.*\n:end\n\z/m, "", true, %w[--verbose -e p(:end)])
     139end
     140
     141assert('mruby --') do
     142  assert_mruby(%{["-x", "1"]\n}, "", true, %w[-e p(ARGV) -- -x 1])
     143end
     144
     145assert('mruby invalid short option') do
     146  assert_mruby("", /\A.*: invalid option -1 .*\n\z/, false, %w[-1])
     147end
     148
     149assert('mruby invalid long option') do
     150  assert_mruby("", /\A.*: invalid option --longopt .*\n\z/, false, %w[--longopt])
     151end
     152
     153assert('unhandled exception') do
     154  assert_mruby("", /\bEXCEPTION\b.*\n\z/, false, %w[-e raise("EXCEPTION")])
     155end
     156
     157assert('program file not found') do
     158  assert_mruby("", /\A.*: Cannot open program file: .*\n\z/, false, %w[_no_exists_])
     159end
     160
     161assert('codegen error') do
     162  code = "def f(#{(1..100).map{|n| "a#{n}"} * ","}); end"
     163  assert_mruby("", /\Acodegen error:.*\n\z/, false, ["-e", code])
     164end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mruby/mrbgem.rake

    r331 r439  
    66  spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
    77  spec.add_dependency('mruby-error', :core => 'mruby-error')
     8  spec.add_test_dependency('mruby-print', :core => 'mruby-print')
    89
    910  if build.cxx_exception_enabled?
    10     @objs << build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c", "#{spec.build_dir}/tools/mruby/mruby.cxx")
    11     @objs.delete_if { |v| v == objfile("#{spec.build_dir}/tools/mruby/mruby") }
     11    build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c", "#{spec.build_dir}/tools/mruby/mruby.cxx")
    1212  end
    1313end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c

    r331 r439  
    1 #include <stdio.h>
     1#include <mruby.h>
     2
     3#ifdef MRB_DISABLE_STDIO
     4# error mruby-bin-mruby conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
     5#endif
     6
    27#include <stdlib.h>
    38#include <string.h>
    4 #include <mruby.h>
    59#include <mruby/array.h>
    610#include <mruby/compile.h>
     
    812#include <mruby/variable.h>
    913
    10 #ifdef MRB_DISABLE_STDIO
    11 static void
    12 p(mrb_state *mrb, mrb_value obj)
    13 {
    14   mrb_value val = mrb_inspect(mrb, obj);
    15 
    16   fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
    17   putc('\n', stdout);
    18 }
    19 #else
    20 #define p(mrb,obj) mrb_p(mrb,obj)
    21 #endif
    22 
    2314struct _args {
    2415  FILE *rfp;
    25   char* cmdline;
     16  char *cmdline;
    2617  mrb_bool fname        : 1;
    2718  mrb_bool mrbfile      : 1;
    2819  mrb_bool check_syntax : 1;
    2920  mrb_bool verbose      : 1;
     21  mrb_bool version      : 1;
     22  mrb_bool debug        : 1;
    3023  int argc;
    31   char** argv;
     24  char **argv;
     25  int libc;
     26  char **libv;
     27};
     28
     29struct options {
     30  int argc;
     31  char **argv;
     32  char *program;
     33  char *opt;
     34  char short_opt[2];
    3235};
    3336
     
    3942  "-b           load and execute RiteBinary (mrb) file",
    4043  "-c           check syntax only",
     44  "-d           set debugging flags (set $DEBUG to true)",
    4145  "-e 'command' one line of script",
     46  "-r library   load the library before executing your script",
    4247  "-v           print version number, then run in verbose mode",
    4348  "--verbose    run in verbose mode",
     
    4853  const char *const *p = usage_msg;
    4954
    50   printf("Usage: %s [switches] programfile\n", name);
     55  printf("Usage: %s [switches] [programfile] [arguments]\n", name);
    5156  while (*p)
    5257    printf("  %s\n", *p++);
    5358}
    5459
     60static void
     61options_init(struct options *opts, int argc, char **argv)
     62{
     63  opts->argc = argc;
     64  opts->argv = argv;
     65  opts->program = *argv;
     66  *opts->short_opt = 0;
     67}
     68
     69static const char *
     70options_opt(struct options *opts)
     71{
     72  /* concatenated short options (e.g. `-cv`) */
     73  if (*opts->short_opt && *++opts->opt) {
     74   short_opt:
     75    opts->short_opt[0] = *opts->opt;
     76    opts->short_opt[1] = 0;
     77    return opts->short_opt;
     78  }
     79
     80  while (++opts->argv, --opts->argc) {
     81    opts->opt = *opts->argv;
     82
     83    /*  empty         || not start with `-`  || `-` */
     84    if (!opts->opt[0] || opts->opt[0] != '-' || !opts->opt[1]) return NULL;
     85
     86    if (opts->opt[1] == '-') {
     87      /* `--` */
     88      if (!opts->opt[2]) {
     89        ++opts->argv, --opts->argc;
     90        return NULL;
     91      }
     92      /* long option */
     93      opts->opt += 2;
     94      *opts->short_opt = 0;
     95      return opts->opt;
     96    }
     97    else {
     98      /* short option */
     99      ++opts->opt;
     100      goto short_opt;
     101    }
     102  }
     103  return NULL;
     104}
     105
     106static const char *
     107options_arg(struct options *opts)
     108{
     109  if (*opts->short_opt && opts->opt[1]) {
     110    /* concatenated short option and option argument (e.g. `-rLIBRARY`) */
     111    *opts->short_opt = 0;
     112    return opts->opt + 1;
     113  }
     114  --opts->argc, ++opts->argv;
     115  return opts->argc ? *opts->argv : NULL;
     116}
     117
     118static char *
     119dup_arg_item(mrb_state *mrb, const char *item)
     120{
     121  size_t buflen = strlen(item) + 1;
     122  char *buf = (char*)mrb_malloc(mrb, buflen);
     123  memcpy(buf, item, buflen);
     124  return buf;
     125}
     126
    55127static int
    56128parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
    57129{
    58   char **origargv = argv;
    59130  static const struct _args args_zero = { 0 };
     131  struct options opts[1];
     132  const char *opt, *item;
    60133
    61134  *args = args_zero;
    62 
    63   for (argc--,argv++; argc > 0; argc--,argv++) {
    64     char *item;
    65     if (argv[0][0] != '-') break;
    66 
    67     if (strlen(*argv) <= 1) {
    68       argc--; argv++;
    69       args->rfp = stdin;
    70       break;
    71     }
    72 
    73     item = argv[0] + 1;
    74     switch (*item++) {
    75     case 'b':
     135  options_init(opts, argc, argv);
     136  while ((opt = options_opt(opts))) {
     137    if (strcmp(opt, "b") == 0) {
    76138      args->mrbfile = TRUE;
    77       break;
    78     case 'c':
     139    }
     140    else if (strcmp(opt, "c") == 0) {
    79141      args->check_syntax = TRUE;
    80       break;
    81     case 'e':
    82       if (item[0]) {
    83         goto append_cmdline;
    84       }
    85       else if (argc > 1) {
    86         argc--; argv++;
    87         item = argv[0];
    88 append_cmdline:
     142    }
     143    else if (strcmp(opt, "d") == 0) {
     144      args->debug = TRUE;
     145    }
     146    else if (strcmp(opt, "e") == 0) {
     147      if ((item = options_arg(opts))) {
    89148        if (!args->cmdline) {
    90           size_t buflen;
    91           char *buf;
    92 
    93           buflen = strlen(item) + 1;
    94           buf = (char *)mrb_malloc(mrb, buflen);
    95           memcpy(buf, item, buflen);
    96           args->cmdline = buf;
     149          args->cmdline = dup_arg_item(mrb, item);
    97150        }
    98151        else {
     
    109162      }
    110163      else {
    111         printf("%s: No code specified for -e\n", *origargv);
    112         return EXIT_SUCCESS;
    113       }
    114       break;
    115     case 'v':
    116       if (!args->verbose) mrb_show_version(mrb);
     164        fprintf(stderr, "%s: No code specified for -e\n", opts->program);
     165        return EXIT_FAILURE;
     166      }
     167    }
     168    else if (strcmp(opt, "h") == 0) {
     169      usage(opts->program);
     170      exit(EXIT_SUCCESS);
     171    }
     172    else if (strcmp(opt, "r") == 0) {
     173      if ((item = options_arg(opts))) {
     174        if (args->libc == 0) {
     175          args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
     176        }
     177        else {
     178          args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
     179        }
     180        args->libv[args->libc++] = dup_arg_item(mrb, item);
     181      }
     182      else {
     183        fprintf(stderr, "%s: No library specified for -r\n", opts->program);
     184        return EXIT_FAILURE;
     185      }
     186    }
     187    else if (strcmp(opt, "v") == 0) {
     188      if (!args->verbose) {
     189        mrb_show_version(mrb);
     190        args->version = TRUE;
     191      }
    117192      args->verbose = TRUE;
    118       break;
    119     case '-':
    120       if (strcmp((*argv) + 2, "version") == 0) {
    121         mrb_show_version(mrb);
    122         exit(EXIT_SUCCESS);
    123       }
    124       else if (strcmp((*argv) + 2, "verbose") == 0) {
    125         args->verbose = TRUE;
    126         break;
    127       }
    128       else if (strcmp((*argv) + 2, "copyright") == 0) {
    129         mrb_show_copyright(mrb);
    130         exit(EXIT_SUCCESS);
    131       }
    132     default:
     193    }
     194    else if (strcmp(opt, "version") == 0) {
     195      mrb_show_version(mrb);
     196      exit(EXIT_SUCCESS);
     197    }
     198    else if (strcmp(opt, "verbose") == 0) {
     199      args->verbose = TRUE;
     200    }
     201    else if (strcmp(opt, "copyright") == 0) {
     202      mrb_show_copyright(mrb);
     203      exit(EXIT_SUCCESS);
     204    }
     205    else {
     206      fprintf(stderr, "%s: invalid option %s%s (-h will show valid options)\n",
     207              opts->program, opt[1] ? "--" : "-", opt);
    133208      return EXIT_FAILURE;
    134209    }
    135210  }
    136211
    137   if (args->rfp == NULL && args->cmdline == NULL) {
    138     if (*argv == NULL) args->rfp = stdin;
    139     else {
    140       args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
     212  argc = opts->argc; argv = opts->argv;
     213  if (args->cmdline == NULL) {
     214    if (*argv == NULL) {
     215      if (args->version) exit(EXIT_SUCCESS);
     216      args->rfp = stdin;
     217    }
     218    else {
     219      args->rfp = strcmp(argv[0], "-") == 0 ?
     220        stdin : fopen(argv[0], args->mrbfile ? "rb" : "r");
    141221      if (args->rfp == NULL) {
    142         printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
     222        fprintf(stderr, "%s: Cannot open program file: %s\n", opts->program, argv[0]);
    143223        return EXIT_FAILURE;
    144224      }
     
    163243    mrb_free(mrb, args->cmdline);
    164244  mrb_free(mrb, args->argv);
     245  if (args->libc) {
     246    while (args->libc--) {
     247      mrb_free(mrb, args->libv[args->libc]);
     248    }
     249    mrb_free(mrb, args->libv);
     250  }
    165251  mrb_close(mrb);
    166252}
     
    179265
    180266  if (mrb == NULL) {
    181     fputs("Invalid mrb_state, exiting mruby\n", stderr);
     267    fprintf(stderr, "%s: Invalid mrb_state, exiting mruby\n", *argv);
    182268    return EXIT_FAILURE;
    183269  }
     
    186272  if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
    187273    cleanup(mrb, &args);
    188     usage(argv[0]);
    189274    return n;
    190275  }
     
    200285    }
    201286    mrb_define_global_const(mrb, "ARGV", ARGV);
     287    mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug));
    202288
    203289    c = mrbc_context_new(mrb);
     
    220306    }
    221307
     308    /* Load libraries */
     309    for (i = 0; i < args.libc; i++) {
     310      FILE *lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r");
     311      if (lfp == NULL) {
     312        fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]);
     313        mrbc_context_free(mrb, c);
     314        cleanup(mrb, &args);
     315        return EXIT_FAILURE;
     316      }
     317      if (args.mrbfile) {
     318        v = mrb_load_irep_file_cxt(mrb, lfp, c);
     319      }
     320      else {
     321        v = mrb_load_file_cxt(mrb, lfp, c);
     322      }
     323      fclose(lfp);
     324    }
     325
    222326    /* Load program */
    223327    if (args.mrbfile) {
     
    237341    mrbc_context_free(mrb, c);
    238342    if (mrb->exc) {
    239       if (mrb_undef_p(v)) {
    240         mrb_p(mrb, mrb_obj_value(mrb->exc));
    241       }
    242       else {
     343      if (!mrb_undef_p(v)) {
    243344        mrb_print_error(mrb);
    244345      }
    245       n = -1;
     346      n = EXIT_FAILURE;
    246347    }
    247348    else if (args.check_syntax) {
    248       printf("Syntax OK\n");
     349      puts("Syntax OK");
    249350    }
    250351  }
    251352  cleanup(mrb, &args);
    252353
    253   return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
    254 }
     354  return n;
     355}
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb

    r321 r439  
    6868  `#{cmd('mruby-strip')} -l #{without_lv.path}`
    6969  assert_true without_lv.size < with_lv.size
    70 
    71   assert_equal '[:a, :b]', `#{cmd('mruby')} -b #{with_lv.path}`.chomp
    72   assert_equal '[]', `#{cmd('mruby')} -b #{without_lv.path}`.chomp
     70#
     71#  assert_equal '[:a, :b]', `#{cmd('mruby')} -b #{with_lv.path}`.chomp
     72#  assert_equal '[]', `#{cmd('mruby')} -b #{without_lv.path}`.chomp
    7373end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c

    r331 r439  
    1 #include <stdio.h>
     1#include <mruby.h>
     2
     3#ifdef MRB_DISABLE_STDIO
     4# error mruby-bin-strip conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
     5#endif
     6
    27#include <stdlib.h>
    38#include <string.h>
    4 #include <mruby.h>
    59#include <mruby/irep.h>
    610#include <mruby/dump.h>
     
    1216  mrb_bool lvar;
    1317};
    14 
    15 
    16 static void
    17 irep_remove_lv(mrb_state *mrb, mrb_irep *irep)
    18 {
    19   size_t i;
    20 
    21   if (irep->lv) {
    22     mrb_free(mrb, irep->lv);
    23     irep->lv = NULL;
    24   }
    25 
    26   for (i = 0; i < irep->rlen; ++i) {
    27     irep_remove_lv(mrb, irep->reps[i]);
    28   }
    29 }
    3018
    3119static void
     
    10088    /* clear lv if --lvar is enabled */
    10189    if (args->lvar) {
    102       irep_remove_lv(mrb, irep);
     90      mrb_irep_remove_lv(mrb, irep);
    10391    }
    10492
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-class-ext/src/class.c

    r331 r439  
    66mrb_mod_name(mrb_state *mrb, mrb_value self)
    77{
    8   mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self));
    9   return mrb_nil_p(name)? name : mrb_str_dup(mrb, name);
     8  mrb_value name =  mrb_class_path(mrb, mrb_class_ptr(self));
     9  if (mrb_string_p(name)) {
     10    MRB_SET_FROZEN_FLAG(mrb_basic_ptr(name));
     11  }
     12  return name;
     13}
     14
     15static mrb_value
     16mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self)
     17{
     18  return mrb_bool_value(mrb_sclass_p(self));
     19}
     20
     21/*
     22 *  call-seq:
     23 *     module_exec(arg...) {|var...| block } -> obj
     24 *     class_exec(arg...) {|var...| block } -> obj
     25 *
     26 * Evaluates the given block in the context of the
     27 * class/module. The method defined in the block will belong
     28 * to the receiver. Any arguments passed to the method will be
     29 * passed to the block. This can be used if the block needs to
     30 * access instance variables.
     31 *
     32 *     class Thing
     33 *     end
     34 *     Thing.class_exec{
     35 *       def hello() "Hello there!" end
     36 *     }
     37 *     puts Thing.new.hello()
     38 */
     39
     40static mrb_value
     41mrb_mod_module_exec(mrb_state *mrb, mrb_value self)
     42{
     43  const mrb_value *argv;
     44  mrb_int argc;
     45  mrb_value blk;
     46
     47  mrb_get_args(mrb, "*&!", &argv, &argc, &blk);
     48
     49  mrb->c->ci->target_class = mrb_class_ptr(self);
     50  return mrb_yield_cont(mrb, blk, self, argc, argv);
    1051}
    1152
     
    1657
    1758  mrb_define_method(mrb, mod, "name", mrb_mod_name, MRB_ARGS_NONE());
     59  mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE());
     60  mrb_define_method(mrb, mod, "module_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK());
     61  mrb_define_method(mrb, mod, "class_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK());
    1862}
    1963
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-class-ext/test/module.rb

    r331 r439  
     1assert 'Module#<' do
     2  a = Class.new
     3  b = Class.new(a)
     4  c = Class.new(a)
     5  d = Module.new
     6  e = Class.new { include d }
     7  f = Module.new { include d }
     8
     9  # compare class to class
     10  assert_true b < a
     11  assert_false b < b
     12  assert_false a < b
     13  assert_nil c < b
     14
     15  # compare class to module
     16  assert_true e < d
     17  assert_false d < e
     18  assert_nil a < d
     19
     20  # compare module to module
     21  assert_true f < d
     22  assert_false f < f
     23  assert_false d < f
     24
     25  assert_raise(TypeError) { a < Object.new }
     26end
     27
     28assert 'Module#<=' do
     29  a = Class.new
     30  b = Class.new(a)
     31  c = Class.new(a)
     32  d = Module.new
     33  e = Class.new { include d }
     34  f = Module.new { include d }
     35
     36  # compare class to class
     37  assert_true b <= a
     38  assert_true b <= b
     39  assert_false a <= b
     40  assert_nil c <= b
     41
     42  # compare class to module
     43  assert_true e <= d
     44  assert_false d <= e
     45  assert_nil a <= d
     46
     47  # compare module to module
     48  assert_true f <= d
     49  assert_true f <= f
     50  assert_false d <= f
     51
     52  assert_raise(TypeError) { a <= Object.new }
     53end
     54
    155assert 'Module#name' do
    2   module A
    3     class B
     56  module Outer
     57    class Inner; end
     58    const_set :SetInner, Class.new
     59  end
     60
     61  assert_equal 'Outer', Outer.name
     62  assert_equal 'Outer::Inner', Outer::Inner.name
     63  assert_equal 'Outer::SetInner', Outer::SetInner.name
     64
     65  outer = Module.new do
     66    const_set :SetInner, Class.new
     67  end
     68  Object.const_set :SetOuter, outer
     69
     70  assert_equal 'SetOuter', SetOuter.name
     71  assert_equal 'SetOuter::SetInner', SetOuter::SetInner.name
     72
     73  mod = Module.new
     74  cls = Class.new
     75
     76  assert_nil mod.name
     77  assert_nil cls.name
     78end
     79
     80assert 'Module#singleton_class?' do
     81  mod = Module.new
     82  cls = Class.new
     83  scl = (class <<cls; self; end)
     84
     85  assert_false mod.singleton_class?
     86  assert_false cls.singleton_class?
     87  assert_true scl.singleton_class?
     88end
     89
     90assert 'Module#module_eval' do
     91  mod = Module.new
     92  mod.class_exec(1,2,3) do |a,b,c|
     93    assert_equal([1,2,3], [a,b,c])
     94    def hi
     95      "hi"
    496    end
    597  end
    6 
    7   assert_nil A::B.singleton_class.name
    8   assert_equal 'Fixnum', Fixnum.name
    9   assert_equal 'A::B', A::B.name
     98  cls = Class.new
     99  cls.class_exec(42) do |x|
     100    assert_equal(42, x)
     101    include mod
     102    def hello
     103      "hello"
     104    end
     105  end
     106  obj = cls.new
     107  assert_equal("hi", obj.hi)
     108  assert_equal("hello", obj.hello)
    10109end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/codegen.c

    r331 r439  
    99#include <stdlib.h>
    1010#include <string.h>
     11#include <math.h>
    1112#include <mruby.h>
    1213#include <mruby/compile.h>
     
    2425#endif
    2526
     27#define MAXARG_S (1<<16)
     28
    2629typedef mrb_ast_node node;
    2730typedef struct mrb_parser_state parser_state;
     
    3740struct loopinfo {
    3841  enum looptype type;
    39   int pc1, pc2, pc3, acc;
     42  int pc0, pc1, pc2, pc3, acc;
    4043  int ensure_level;
    4144  struct loopinfo *prev;
     
    5154  node *lv;
    5255
    53   int sp;
    54   int pc;
    55   int lastlabel;
     56  uint16_t sp;
     57  uint16_t pc;
     58  uint16_t lastpc;
     59  uint16_t lastlabel;
    5660  int ainfo:15;
    5761  mrb_bool mscope:1;
     
    5963  struct loopinfo *loop;
    6064  int ensure_level;
    61   char const *filename;
     65  mrb_sym filename_sym;
    6266  uint16_t lineno;
    6367
    6468  mrb_code *iseq;
    6569  uint16_t *lines;
    66   int icapa;
     70  uint32_t icapa;
    6771
    6872  mrb_irep *irep;
    69   size_t pcapa;
    70   size_t scapa;
    71   size_t rcapa;
     73  uint32_t pcapa, scapa, rcapa;
    7274
    7375  uint16_t nlocals;
     
    101103    codegen_scope *tmp = s->prev;
    102104    mrb_free(s->mrb, s->iseq);
     105    mrb_free(s->mrb, s->lines);
    103106    mrb_pool_close(s->mpool);
    104107    s = tmp;
    105108  }
    106109#ifndef MRB_DISABLE_STDIO
    107   if (s->filename && s->lineno) {
    108     fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message);
     110  if (s->filename_sym && s->lineno) {
     111    const char *filename = mrb_sym_name_len(s->mrb, s->filename_sym, NULL);
     112    fprintf(stderr, "codegen error:%s:%d: %s\n", filename, s->lineno, message);
    109113  }
    110114  else {
     
    125129
    126130static void*
    127 codegen_malloc(codegen_scope *s, size_t len)
    128 {
    129   void *p = mrb_malloc_simple(s->mrb, len);
    130 
    131   if (!p) codegen_error(s, "mrb_malloc");
    132   return p;
    133 }
    134 
    135 static void*
    136131codegen_realloc(codegen_scope *s, void *p, size_t len)
    137132{
     
    145140new_label(codegen_scope *s)
    146141{
    147   s->lastlabel = s->pc;
    148   return s->pc;
    149 }
    150 
    151 static inline int
    152 genop(codegen_scope *s, mrb_code i)
    153 {
    154   if (s->pc == s->icapa) {
     142  return s->lastlabel = s->pc;
     143}
     144
     145static void
     146emit_B(codegen_scope *s, uint32_t pc, uint8_t i)
     147{
     148  if (pc >= MAXARG_S || s->icapa >= MAXARG_S) {
     149    codegen_error(s, "too big code block");
     150  }
     151  if (pc >= s->icapa) {
    155152    s->icapa *= 2;
     153    if (s->icapa > MAXARG_S) {
     154      s->icapa = MAXARG_S;
     155    }
    156156    s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa);
    157157    if (s->lines) {
    158       s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(short)*s->icapa);
    159       s->irep->lines = s->lines;
    160     }
    161   }
    162   s->iseq[s->pc] = i;
     158      s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->icapa);
     159    }
     160  }
    163161  if (s->lines) {
    164     s->lines[s->pc] = s->lineno;
    165   }
    166   return s->pc++;
     162    if (s->lineno > 0 || pc == 0)
     163      s->lines[pc] = s->lineno;
     164    else
     165      s->lines[pc] = s->lines[pc-1];
     166  }
     167  s->iseq[pc] = i;
     168}
     169
     170static void
     171emit_S(codegen_scope *s, int pc, uint16_t i)
     172{
     173  uint8_t hi = i>>8;
     174  uint8_t lo = i&0xff;
     175
     176  emit_B(s, pc,   hi);
     177  emit_B(s, pc+1, lo);
     178}
     179
     180static void
     181gen_B(codegen_scope *s, uint8_t i)
     182{
     183  emit_B(s, s->pc, i);
     184  s->pc++;
     185}
     186
     187static void
     188gen_S(codegen_scope *s, uint16_t i)
     189{
     190  emit_S(s, s->pc, i);
     191  s->pc += 2;
     192}
     193
     194static void
     195genop_0(codegen_scope *s, mrb_code i)
     196{
     197  s->lastpc = s->pc;
     198  gen_B(s, i);
     199}
     200
     201static void
     202genop_1(codegen_scope *s, mrb_code i, uint16_t a)
     203{
     204  s->lastpc = s->pc;
     205  if (a > 0xff) {
     206    gen_B(s, OP_EXT1);
     207    gen_B(s, i);
     208    gen_S(s, a);
     209  }
     210  else {
     211    gen_B(s, i);
     212    gen_B(s, (uint8_t)a);
     213  }
     214}
     215
     216static void
     217genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b)
     218{
     219  s->lastpc = s->pc;
     220  if (a > 0xff && b > 0xff) {
     221    gen_B(s, OP_EXT3);
     222    gen_B(s, i);
     223    gen_S(s, a);
     224    gen_S(s, b);
     225  }
     226  else if (b > 0xff) {
     227    gen_B(s, OP_EXT2);
     228    gen_B(s, i);
     229    gen_B(s, (uint8_t)a);
     230    gen_S(s, b);
     231  }
     232  else if (a > 0xff) {
     233    gen_B(s, OP_EXT1);
     234    gen_B(s, i);
     235    gen_S(s, a);
     236    gen_B(s, (uint8_t)b);
     237  }
     238  else {
     239    gen_B(s, i);
     240    gen_B(s, (uint8_t)a);
     241    gen_B(s, (uint8_t)b);
     242  }
     243}
     244
     245static void
     246genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c)
     247{
     248  genop_2(s, i, a, b);
     249  gen_B(s, c);
     250}
     251
     252static void
     253genop_2S(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b)
     254{
     255  genop_1(s, i, a);
     256  gen_S(s, b);
     257}
     258
     259static void
     260genop_W(codegen_scope *s, mrb_code i, uint32_t a)
     261{
     262  uint8_t a1 = (a>>16) & 0xff;
     263  uint8_t a2 = (a>>8) & 0xff;
     264  uint8_t a3 = a & 0xff;
     265
     266  s->lastpc = s->pc;
     267  gen_B(s, i);
     268  gen_B(s, a1);
     269  gen_B(s, a2);
     270  gen_B(s, a3);
    167271}
    168272
     
    178282}
    179283
    180 static int
    181 genop_peep(codegen_scope *s, mrb_code i, int val)
    182 {
    183   /* peephole optimization */
    184   if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) {
    185     mrb_code i0 = s->iseq[s->pc-1];
    186     int c1 = GET_OPCODE(i);
    187     int c0 = GET_OPCODE(i0);
    188 
    189     switch (c1) {
     284static
     285mrb_bool
     286on_eval(codegen_scope *s)
     287{
     288  if (s && s->parser && s->parser->on_eval)
     289    return TRUE;
     290  return FALSE;
     291}
     292
     293struct mrb_insn_data
     294mrb_decode_insn(const mrb_code *pc)
     295{
     296  struct mrb_insn_data data = { 0 };
     297  mrb_code insn = READ_B();
     298  uint16_t a = 0;
     299  uint16_t b = 0;
     300  uint8_t  c = 0;
     301
     302  switch (insn) {
     303#define FETCH_Z() /* empty */
     304#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x (); break;
     305#include "mruby/ops.h"
     306#undef OPCODE
     307  }
     308  switch (insn) {
     309  case OP_EXT1:
     310    insn = READ_B();
     311    switch (insn) {
     312#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); break;
     313#include "mruby/ops.h"
     314#undef OPCODE
     315    }
     316    break;
     317  case OP_EXT2:
     318    insn = READ_B();
     319    switch (insn) {
     320#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); break;
     321#include "mruby/ops.h"
     322#undef OPCODE
     323    }
     324    break;
     325  case OP_EXT3:
     326    insn = READ_B();
     327    switch (insn) {
     328#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); break;
     329#include "mruby/ops.h"
     330#undef OPCODE
     331    }
     332    break;
     333  default:
     334    break;
     335  }
     336  data.insn = insn;
     337  data.a = a;
     338  data.b = b;
     339  data.c = c;
     340  return data;
     341}
     342
     343static struct mrb_insn_data
     344mrb_last_insn(codegen_scope *s)
     345{
     346  if (s->pc == s->lastpc) {
     347    struct mrb_insn_data data;
     348
     349    data.insn = OP_NOP;
     350    return data;
     351  }
     352  return mrb_decode_insn(&s->iseq[s->lastpc]);
     353}
     354
     355static mrb_bool
     356no_peephole(codegen_scope *s)
     357{
     358  return no_optimize(s) || s->lastlabel == s->pc || s->pc == 0 || s->pc == s->lastpc;
     359}
     360
     361static uint16_t
     362genjmp(codegen_scope *s, mrb_code i, uint16_t pc)
     363{
     364  uint16_t pos;
     365
     366  s->lastpc = s->pc;
     367  gen_B(s, i);
     368  pos = s->pc;
     369  gen_S(s, pc);
     370  return pos;
     371}
     372
     373static uint16_t
     374genjmp2(codegen_scope *s, mrb_code i, uint16_t a, int pc, int val)
     375{
     376  uint16_t pos;
     377
     378  if (!no_peephole(s) && !val) {
     379    struct mrb_insn_data data = mrb_last_insn(s);
     380
     381    if (data.insn == OP_MOVE && data.a == a) {
     382      s->pc = s->lastpc;
     383      a = data.b;
     384    }
     385  }
     386
     387  s->lastpc = s->pc;
     388  if (a > 0xff) {
     389    gen_B(s, OP_EXT1);
     390    gen_B(s, i);
     391    gen_S(s, a);
     392    pos = s->pc;
     393    gen_S(s, pc);
     394  }
     395  else {
     396    gen_B(s, i);
     397    gen_B(s, (uint8_t)a);
     398    pos = s->pc;
     399    gen_S(s, pc);
     400  }
     401  return pos;
     402}
     403
     404static void
     405gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
     406{
     407  if (no_peephole(s)) {
     408  normal:
     409    genop_2(s, OP_MOVE, dst, src);
     410    if (on_eval(s)) {
     411      genop_0(s, OP_NOP);
     412    }
     413    return;
     414  }
     415  else {
     416    struct mrb_insn_data data = mrb_last_insn(s);
     417
     418    switch (data.insn) {
    190419    case OP_MOVE:
    191       if (GETARG_A(i) == GETARG_B(i)) {
    192         /* skip useless OP_MOVE */
    193         return 0;
    194       }
    195       if (val) break;
    196       switch (c0) {
    197       case OP_MOVE:
    198         if (GETARG_A(i) == GETARG_A(i0)) {
    199           /* skip overriden OP_MOVE */
    200           s->pc--;
    201           s->iseq[s->pc] = i;
    202         }
    203         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) {
    204           /* skip swapping OP_MOVE */
    205           return 0;
    206         }
    207         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    208           s->pc--;
    209           return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val);
    210         }
    211         break;
    212       case OP_LOADI:
    213         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    214           s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0));
    215           return 0;
    216         }
    217         break;
    218       case OP_ARRAY:
    219       case OP_HASH:
    220       case OP_RANGE:
    221       case OP_AREF:
    222       case OP_GETUPVAR:
    223         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    224           s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0));
    225           return 0;
    226         }
    227         break;
    228       case OP_LOADSYM:
    229       case OP_GETGLOBAL:
    230       case OP_GETIV:
    231       case OP_GETCV:
    232       case OP_GETCONST:
    233       case OP_GETSPECIAL:
    234       case OP_LOADL:
    235       case OP_STRING:
    236         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    237           s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0));
    238           return 0;
    239         }
    240         break;
    241       case OP_SCLASS:
    242         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    243           s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
    244           return 0;
    245         }
    246         break;
    247       case OP_LOADNIL:
    248       case OP_LOADSELF:
    249       case OP_LOADT:
    250       case OP_LOADF:
    251       case OP_OCLASS:
    252         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    253           s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i));
    254           return 0;
    255         }
    256         break;
    257       default:
    258         break;
    259       }
     420      if (dst == src) return;             /* remove useless MOVE */
     421      if (data.b == dst && data.a == src) /* skip swapping MOVE */
     422        return;
     423      goto normal;
     424    case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF:
     425    case OP_LOADI__1:
     426    case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3:
     427    case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7:
     428      if (nopeep || data.a != src || data.a < s->nlocals) goto normal;
     429      s->pc = s->lastpc;
     430      genop_1(s, data.insn, dst);
    260431      break;
    261     case OP_SETIV:
    262     case OP_SETCV:
    263     case OP_SETCONST:
    264     case OP_SETMCNST:
    265     case OP_SETGLOBAL:
    266       if (val) break;
    267       if (c0 == OP_MOVE) {
    268         if (GETARG_A(i) == GETARG_A(i0)) {
    269           s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i));
    270           return 0;
    271         }
    272       }
    273       break;
    274     case OP_SETUPVAR:
    275       if (val) break;
    276       if (c0 == OP_MOVE) {
    277         if (GETARG_A(i) == GETARG_A(i0)) {
    278           s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i));
    279           return 0;
    280         }
    281       }
    282       break;
    283     case OP_EPOP:
    284       if (c0 == OP_EPOP) {
    285         s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i));
    286         return 0;
    287       }
    288       break;
    289     case OP_POPERR:
    290       if (c0 == OP_POPERR) {
    291         s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i));
    292         return 0;
    293       }
    294       break;
    295     case OP_RETURN:
    296       switch (c0) {
    297       case OP_RETURN:
    298         return 0;
    299       case OP_MOVE:
    300         if (GETARG_A(i0) >= s->nlocals) {
    301           s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
    302           return 0;
    303         }
    304         break;
    305       case OP_SETIV:
    306       case OP_SETCV:
    307       case OP_SETCONST:
    308       case OP_SETMCNST:
    309       case OP_SETUPVAR:
    310       case OP_SETGLOBAL:
    311         s->pc--;
    312         genop_peep(s, i0, NOVAL);
    313         i0 = s->iseq[s->pc-1];
    314         return genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL));
    315 #if 0
    316       case OP_SEND:
    317         if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) {
    318           s->iseq[s->pc-1] = MKOP_ABC(OP_TAILCALL, GETARG_A(i0), GETARG_B(i0), GETARG_C(i0));
    319           return;
    320         }
    321         break;
    322 #endif
    323       default:
    324         break;
    325       }
    326       break;
    327     case OP_ADD:
    328     case OP_SUB:
    329       if (c0 == OP_LOADI) {
    330         int c = GETARG_sBx(i0);
    331 
    332         if (c1 == OP_SUB) c = -c;
    333         if (c > 127 || c < -127) break;
    334         if (0 <= c)
    335           s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c);
    336         else
    337           s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c);
    338         return 0;
    339       }
    340     case OP_STRCAT:
    341       if (c0 == OP_STRING) {
    342         mrb_value v = s->irep->pool[GETARG_Bx(i0)];
    343 
    344         if (mrb_string_p(v) && RSTRING_LEN(v) == 0) {
    345           s->pc--;
    346           return 0;
    347         }
    348       }
    349       if (c0 == OP_LOADNIL) {
    350         if (GETARG_B(i) == GETARG_A(i0)) {
    351           s->pc--;
    352           return 0;
    353         }
    354       }
    355       break;
    356     case OP_JMPIF:
    357     case OP_JMPNOT:
    358       if (c0 == OP_MOVE && GETARG_A(i) == GETARG_A(i0)) {
    359         s->iseq[s->pc-1] = MKOP_AsBx(c1, GETARG_B(i0), GETARG_sBx(i));
    360         return s->pc-1;
    361       }
     432    case OP_LOADI: case OP_LOADINEG: case OP_LOADL: case OP_LOADSYM:
     433    case OP_GETGV: case OP_GETSV: case OP_GETIV: case OP_GETCV:
     434    case OP_GETCONST: case OP_STRING:
     435    case OP_LAMBDA: case OP_BLOCK: case OP_METHOD: case OP_BLKPUSH:
     436      if (nopeep || data.a != src || data.a < s->nlocals) goto normal;
     437      s->pc = s->lastpc;
     438      genop_2(s, data.insn, dst, data.b);
    362439      break;
    363440    default:
     441      goto normal;
     442    }
     443  }
     444}
     445
     446static void
     447gen_return(codegen_scope *s, uint8_t op, uint16_t src)
     448{
     449  if (no_peephole(s)) {
     450    genop_1(s, op, src);
     451  }
     452  else {
     453    struct mrb_insn_data data = mrb_last_insn(s);
     454
     455    if (data.insn == OP_MOVE && src == data.a) {
     456      s->pc = s->lastpc;
     457      genop_1(s, op, data.b);
     458    }
     459    else if (data.insn != OP_RETURN) {
     460      genop_1(s, op, src);
     461    }
     462  }
     463}
     464
     465static void
     466gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst)
     467{
     468  if (no_peephole(s)) {
     469  normal:
     470    genop_1(s, op, dst);
     471    return;
     472  }
     473  else {
     474    struct mrb_insn_data data = mrb_last_insn(s);
     475
     476    switch (data.insn) {
     477    case OP_LOADI__1:
     478      if (op == OP_ADD) op = OP_SUB;
     479      else op = OP_ADD;
     480      data.b = 1;
     481      goto replace;
     482    case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3:
     483    case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7:
     484      data.b = data.insn - OP_LOADI_0;
     485      /* fall through */
     486    case OP_LOADI:
     487    replace:
     488      if (data.b >= 128) goto normal;
     489      s->pc = s->lastpc;
     490      if (op == OP_ADD) {
     491        genop_2(s, OP_ADDI, dst, (uint8_t)data.b);
     492      }
     493      else {
     494        genop_2(s, OP_SUBI, dst, (uint8_t)data.b);
     495      }
    364496      break;
    365     }
    366   }
    367   return genop(s, i);
     497    default:
     498      goto normal;
     499    }
     500  }
     501}
     502
     503static int
     504dispatch(codegen_scope *s, uint16_t pos0)
     505{
     506  uint16_t newpos;
     507
     508  s->lastlabel = s->pc;
     509  newpos = PEEK_S(s->iseq+pos0);
     510  emit_S(s, pos0, s->pc);
     511  return newpos;
    368512}
    369513
    370514static void
    371 scope_error(codegen_scope *s)
    372 {
    373   exit(EXIT_FAILURE);
    374 }
    375 
    376 static inline void
    377 dispatch(codegen_scope *s, int pc)
    378 {
    379   int diff = s->pc - pc;
    380   mrb_code i = s->iseq[pc];
    381   int c = GET_OPCODE(i);
    382 
    383   s->lastlabel = s->pc;
    384   switch (c) {
    385   case OP_JMP:
    386   case OP_JMPIF:
    387   case OP_JMPNOT:
    388   case OP_ONERR:
    389     break;
    390   default:
    391 #ifndef MRB_DISABLE_STDIO
    392     fprintf(stderr, "bug: dispatch on non JMP op\n");
    393 #endif
    394     scope_error(s);
    395     break;
    396   }
    397   if (diff > MAXARG_sBx) {
    398     codegen_error(s, "too distant jump address");
    399   }
    400   s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff);
    401 }
    402 
    403 static void
    404 dispatch_linked(codegen_scope *s, int pc)
    405 {
    406   mrb_code i;
    407   int pos;
    408 
    409   if (!pc) return;
     515dispatch_linked(codegen_scope *s, uint16_t pos)
     516{
     517  if (pos==0) return;
    410518  for (;;) {
    411     i = s->iseq[pc];
    412     pos = GETARG_sBx(i);
    413     dispatch(s, pc);
    414     if (!pos) break;
    415     pc = pos;
     519    pos = dispatch(s, pos);
     520    if (pos==0) break;
    416521  }
    417522}
     
    419524#define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
    420525static void
    421 push_(codegen_scope *s)
    422 {
    423   if (s->sp > 511) {
    424     codegen_error(s, "too complex expression");
    425   }
    426   s->sp++;
    427   nregs_update;
    428 }
    429 
    430 static void
    431 push_n_(codegen_scope *s, size_t n)
    432 {
    433   if (s->sp+n > 511) {
     526push_n_(codegen_scope *s, int n)
     527{
     528  if (s->sp+n >= 0xffff) {
    434529    codegen_error(s, "too complex expression");
    435530  }
     
    438533}
    439534
    440 #define push() push_(s)
     535static void
     536pop_n_(codegen_scope *s, int n)
     537{
     538  if ((int)s->sp-n < 0) {
     539    codegen_error(s, "stack pointer underflow");
     540  }
     541  s->sp-=n;
     542}
     543
     544#define push() push_n_(s,1)
    441545#define push_n(n) push_n_(s,n)
    442 #define pop_(s) ((s)->sp--)
    443 #define pop() pop_(s)
    444 #define pop_n(n) (s->sp-=(n))
     546#define pop() pop_n_(s,1)
     547#define pop_n(n) pop_n_(s,n)
    445548#define cursp() (s->sp)
    446549
     
    448551new_lit(codegen_scope *s, mrb_value val)
    449552{
    450   size_t i;
     553  int i;
    451554  mrb_value *pv;
    452555
     
    457560      pv = &s->irep->pool[i];
    458561
    459       if (mrb_type(*pv) != MRB_TT_STRING) continue;
     562      if (!mrb_string_p(*pv)) continue;
    460563      if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue;
    461564      if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0)
     
    463566    }
    464567    break;
     568#ifndef MRB_WITHOUT_FLOAT
    465569  case MRB_TT_FLOAT:
    466570    for (i=0; i<s->irep->plen; i++) {
     571      mrb_float f1, f2;
    467572      pv = &s->irep->pool[i];
    468       if (mrb_type(*pv) != MRB_TT_FLOAT) continue;
    469       if (mrb_float(*pv) == mrb_float(val)) return i;
    470     }
    471     break;
     573      if (!mrb_float_p(*pv)) continue;
     574      f1 = mrb_float(*pv);
     575      f2 = mrb_float(val);
     576      if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i;
     577    }
     578    break;
     579#endif
    472580  case MRB_TT_FIXNUM:
    473581    for (i=0; i<s->irep->plen; i++) {
     
    492600  switch (mrb_type(val)) {
    493601  case MRB_TT_STRING:
    494     *pv = mrb_str_pool(s->mrb, val);
    495     break;
    496 
     602    *pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val)));
     603    break;
     604
     605#ifndef MRB_WITHOUT_FLOAT
    497606  case MRB_TT_FLOAT:
    498607#ifdef MRB_WORD_BOXING
     
    500609    break;
    501610#endif
     611#endif
    502612  case MRB_TT_FIXNUM:
    503613    *pv = val;
     
    511621}
    512622
    513 /* method symbols should be fit in 9 bits */
    514 #define MAXMSYMLEN 512
    515623/* maximum symbol numbers */
    516 #define MAXSYMLEN 65536
     624#define MAXSYMLEN 0x10000
    517625
    518626static int
    519 new_msym(codegen_scope *s, mrb_sym sym)
    520 {
    521   size_t i, len;
     627new_sym(codegen_scope *s, mrb_sym sym)
     628{
     629  int i, len;
    522630
    523631  mrb_assert(s->irep);
    524632
    525633  len = s->irep->slen;
    526   if (len > MAXMSYMLEN) len = MAXMSYMLEN;
    527634  for (i=0; i<len; i++) {
    528635    if (s->irep->syms[i] == sym) return i;
    529     if (s->irep->syms[i] == 0) break;
    530   }
    531   if (i == MAXMSYMLEN) {
    532     codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN) ")");
    533   }
    534   s->irep->syms[i] = sym;
    535   if (i == s->irep->slen) s->irep->slen++;
    536   return i;
    537 }
    538 
    539 static int
    540 new_sym(codegen_scope *s, mrb_sym sym)
    541 {
    542   size_t i;
    543 
    544   for (i=0; i<s->irep->slen; i++) {
    545     if (s->irep->syms[i] == sym) return i;
    546   }
    547   if (s->irep->slen == MAXSYMLEN) {
    548     codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN) ")");
    549   }
    550 
    551   if (s->irep->slen > MAXMSYMLEN/2 && s->scapa == MAXMSYMLEN) {
    552     s->scapa = MAXSYMLEN;
    553     s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*MAXSYMLEN);
    554     for (i = s->irep->slen; i < MAXMSYMLEN; i++) {
    555       static const mrb_sym mrb_sym_zero = { 0 };
    556       s->irep->syms[i] = mrb_sym_zero;
    557     }
    558     s->irep->slen = MAXMSYMLEN;
     636  }
     637  if (s->irep->slen >= s->scapa) {
     638    s->scapa *= 2;
     639    s->irep->syms = (mrb_sym*)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*s->scapa);
    559640  }
    560641  s->irep->syms[s->irep->slen] = sym;
     
    574655}
    575656
    576 #define sym(x) ((mrb_sym)(intptr_t)(x))
    577 #define lv_name(lv) sym((lv)->car)
     657#define nint(x) ((int)(intptr_t)(x))
     658#define nchar(x) ((char)(intptr_t)(x))
     659#define nsym(x) ((mrb_sym)(intptr_t)(x))
     660
     661#define lv_name(lv) nsym((lv)->car)
     662
    578663static int
    579664lv_idx(codegen_scope *s, mrb_sym id)
     
    597682  struct loopinfo *lp;
    598683  node *n2;
    599   mrb_code c;
    600684
    601685  /* generate receiver */
     
    603687  /* generate loop-block */
    604688  s = scope_new(s->mrb, s, NULL);
    605   if (s == NULL) {
    606     raise_error(prev, "unexpected scope");
    607   }
    608689
    609690  push();                       /* push for a block parameter */
     
    611692  /* generate loop variable */
    612693  n2 = tree->car;
    613   genop(s, MKOP_Ax(OP_ENTER, 0x40000));
     694  genop_W(s, OP_ENTER, 0x40000);
    614695  if (n2->car && !n2->car->cdr && !n2->cdr) {
    615696    gen_assignment(s, n2->car->car, 1, NOVAL);
     
    625706  codegen(s, tree->cdr->cdr->car, VAL);
    626707  pop();
    627   if (s->pc > 0) {
    628     c = s->iseq[s->pc-1];
    629     if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel)
    630       genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
    631   }
     708  gen_return(s, OP_RETURN, cursp());
    632709  loop_pop(s, NOVAL);
    633710  scope_finish(s);
    634711  s = prev;
    635   genop(s, MKOP_Abc(OP_LAMBDA, cursp(), s->irep->rlen-1, OP_L_BLOCK));
     712  genop_2(s, OP_BLOCK, cursp(), s->irep->rlen-1);
     713  push();pop(); /* space for a block */
    636714  pop();
    637   idx = new_msym(s, mrb_intern_lit(s->mrb, "each"));
    638   genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));
     715  idx = new_sym(s, mrb_intern_lit(s->mrb, "each"));
     716  genop_3(s, OP_SENDB, cursp(), idx, 0);
    639717}
    640718
     
    642720lambda_body(codegen_scope *s, node *tree, int blk)
    643721{
    644   mrb_code c;
    645722  codegen_scope *parent = s;
    646723  s = scope_new(s->mrb, s, tree->car);
    647   if (s == NULL) {
    648     raise_error(parent, "unexpected scope");
    649   }
    650724
    651725  s->mscope = !blk;
     
    653727  if (blk) {
    654728    struct loopinfo *lp = loop_push(s, LOOP_BLOCK);
    655     lp->pc1 = new_label(s);
     729    lp->pc0 = new_label(s);
    656730  }
    657731  tree = tree->cdr;
    658   if (tree->car) {
     732  if (tree->car == NULL) {
     733    genop_W(s, OP_ENTER, 0);
     734  }
     735  else {
    659736    mrb_aspec a;
    660737    int ma, oa, ra, pa, ka, kd, ba;
    661738    int pos, i;
    662     node *n, *opt;
    663 
     739    node *opt;
     740    node *margs, *pargs;
     741    node *tail;
     742
     743    /* mandatory arguments */
    664744    ma = node_len(tree->car->car);
    665     n = tree->car->car;
    666     while (n) {
    667       n = n->cdr;
    668     }
     745    margs = tree->car->car;
     746    tail = tree->car->cdr->cdr->cdr->cdr;
     747
     748    /* optional arguments */
    669749    oa = node_len(tree->car->cdr->car);
     750    /* rest argument? */
    670751    ra = tree->car->cdr->cdr->car ? 1 : 0;
     752    /* mandatory arugments after rest argument */
    671753    pa = node_len(tree->car->cdr->cdr->cdr->car);
    672     ka = kd = 0;
    673     ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0;
     754    pargs = tree->car->cdr->cdr->cdr->car;
     755    /* keyword arguments */
     756    ka = tail? node_len(tail->cdr->car) : 0;
     757    /* keyword dictionary? */
     758    kd = tail && tail->cdr->cdr->car? 1 : 0;
     759    /* block argument? */
     760    ba = tail && tail->cdr->cdr->cdr->car ? 1 : 0;
    674761
    675762    if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) {
    676763      codegen_error(s, "too many formal arguments");
    677764    }
    678     a = ((mrb_aspec)(ma & 0x1f) << 18)
    679       | ((mrb_aspec)(oa & 0x1f) << 13)
    680       | ((ra & 1) << 12)
    681       | ((pa & 0x1f) << 7)
    682       | ((ka & 0x1f) << 2)
    683       | ((kd & 1)<< 1)
    684       | (ba & 1);
    685     s->ainfo = (((ma+oa) & 0x3f) << 6) /* (12bits = 6:1:5) */
    686       | ((ra & 1) << 5)
    687       | (pa & 0x1f);
    688     genop(s, MKOP_Ax(OP_ENTER, a));
     765    a = MRB_ARGS_REQ(ma)
     766      | MRB_ARGS_OPT(oa)
     767      | (ra? MRB_ARGS_REST() : 0)
     768      | MRB_ARGS_POST(pa)
     769      | MRB_ARGS_KEY(ka, kd)
     770      | (ba? MRB_ARGS_BLOCK() : 0);
     771    s->ainfo = (((ma+oa) & 0x3f) << 7) /* (12bits = 5:1:5:1) */
     772      | ((ra & 0x1) << 6)
     773      | ((pa & 0x1f) << 1)
     774      | ((ka | kd) != 0 ? 0x01 : 0x00);
     775    genop_W(s, OP_ENTER, a);
     776    /* generate jump table for optional arguments initializer */
    689777    pos = new_label(s);
    690778    for (i=0; i<oa; i++) {
    691779      new_label(s);
    692       genop(s, MKOP_sBx(OP_JMP, 0));
     780      genjmp(s, OP_JMP, 0);
    693781    }
    694782    if (oa > 0) {
    695       genop(s, MKOP_sBx(OP_JMP, 0));
     783      genjmp(s, OP_JMP, 0);
    696784    }
    697785    opt = tree->car->cdr->car;
     
    700788      int idx;
    701789
    702       dispatch(s, pos+i);
     790      dispatch(s, pos+i*3+1);
    703791      codegen(s, opt->car->cdr, VAL);
    704       idx = lv_idx(s, (mrb_sym)(intptr_t)opt->car->car);
    705792      pop();
    706       genop_peep(s, MKOP_AB(OP_MOVE, idx, cursp()), NOVAL);
     793      idx = lv_idx(s, nsym(opt->car->car));
     794      gen_move(s, idx, cursp(), 0);
    707795      i++;
    708796      opt = opt->cdr;
    709797    }
    710798    if (oa > 0) {
    711       dispatch(s, pos+i);
    712     }
    713   }
     799      dispatch(s, pos+i*3+1);
     800    }
     801
     802    /* keyword arguments */
     803    if (tail) {
     804      node *kwds = tail->cdr->car;
     805      int kwrest = 0;
     806
     807      if (tail->cdr->cdr->car) {
     808        kwrest = 1;
     809      }
     810      mrb_assert(nint(tail->car) == NODE_ARGS_TAIL);
     811      mrb_assert(node_len(tail) == 4);
     812
     813      while (kwds) {
     814        int jmpif_key_p, jmp_def_set = -1;
     815        node *kwd = kwds->car, *def_arg = kwd->cdr->cdr->car;
     816        mrb_sym kwd_sym = nsym(kwd->cdr->car);
     817
     818        mrb_assert(nint(kwd->car) == NODE_KW_ARG);
     819
     820        if (def_arg) {
     821          genop_2(s, OP_KEY_P, lv_idx(s, kwd_sym), new_sym(s, kwd_sym));
     822          jmpif_key_p = genjmp2(s, OP_JMPIF, lv_idx(s, kwd_sym), 0, 0);
     823          codegen(s, def_arg, VAL);
     824          pop();
     825          gen_move(s, lv_idx(s, kwd_sym), cursp(), 0);
     826          jmp_def_set = genjmp(s, OP_JMP, 0);
     827          dispatch(s, jmpif_key_p);
     828        }
     829        genop_2(s, OP_KARG, lv_idx(s, kwd_sym), new_sym(s, kwd_sym));
     830        if (jmp_def_set != -1) {
     831          dispatch(s, jmp_def_set);
     832        }
     833        i++;
     834
     835        kwds = kwds->cdr;
     836      }
     837      if (tail->cdr->car && !kwrest) {
     838        genop_0(s, OP_KEYEND);
     839      }
     840    }
     841
     842    /* argument destructuring */
     843    if (margs) {
     844      node *n = margs;
     845
     846      pos = 1;
     847      while (n) {
     848        if (nint(n->car->car) == NODE_MASGN) {
     849          gen_vmassignment(s, n->car->cdr->car, pos, NOVAL);
     850        }
     851        pos++;
     852        n = n->cdr;
     853      }
     854    }
     855    if (pargs) {
     856      node *n = margs;
     857
     858      pos = ma+oa+ra+1;
     859      while (n) {
     860        if (nint(n->car->car) == NODE_MASGN) {
     861          gen_vmassignment(s, n->car->cdr->car, pos, NOVAL);
     862        }
     863        pos++;
     864        n = n->cdr;
     865      }
     866    }
     867  }
     868
    714869  codegen(s, tree->cdr->car, VAL);
    715870  pop();
    716871  if (s->pc > 0) {
    717     c = s->iseq[s->pc-1];
    718     if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
    719       if (s->nregs == 0) {
    720         genop(s, MKOP_A(OP_LOADNIL, 0));
    721         genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
    722       }
    723       else {
    724         genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
    725       }
    726     }
     872    gen_return(s, OP_RETURN, cursp());
    727873  }
    728874  if (blk) {
     
    737883{
    738884  codegen_scope *scope = scope_new(s->mrb, s, tree->car);
    739   if (scope == NULL) {
    740     raise_error(s, "unexpected scope");
    741   }
    742885
    743886  codegen(scope, tree->cdr, VAL);
     887  gen_return(scope, OP_RETURN, scope->sp-1);
    744888  if (!s->iseq) {
    745     genop(scope, MKOP_A(OP_STOP, 0));
    746   }
    747   else if (!val) {
    748     genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
    749   }
    750   else {
    751     if (scope->nregs == 0) {
    752       genop(scope, MKOP_A(OP_LOADNIL, 0));
    753       genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
    754     }
    755     else {
    756       genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp-1, OP_R_NORMAL), NOVAL);
    757     }
     889    genop_0(scope, OP_STOP);
    758890  }
    759891  scope_finish(scope);
     
    769901{
    770902  while (t) {
    771     if ((intptr_t)t->car->car == NODE_SPLAT) return FALSE;
     903    if (nint(t->car->car) == NODE_SPLAT) return FALSE;
    772904    t = t->cdr;
    773905  }
     
    782914  char *name2;
    783915
    784   name = mrb_sym2name_len(s->mrb, a, &len);
     916  name = mrb_sym_name_len(s->mrb, a, &len);
    785917  name2 = (char *)codegen_palloc(s,
    786918                                 (size_t)len
     
    805937
    806938  while (t) {
    807     is_splat = (intptr_t)t->car->car == NODE_SPLAT; /* splat mode */
     939    is_splat = nint(t->car->car) == NODE_SPLAT; /* splat mode */
    808940    if (
    809941      n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */
    810942      || is_splat) {
    811943      if (val) {
    812         if (is_splat && n == 0 && (intptr_t)t->car->cdr->car == NODE_ARRAY) {
     944        if (is_splat && n == 0 && nint(t->car->cdr->car) == NODE_ARRAY) {
    813945          codegen(s, t->car->cdr, VAL);
    814946          pop();
     
    816948        else {
    817949          pop_n(n);
    818           genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
     950          if (n == 0 && is_splat) {
     951            genop_1(s, OP_LOADNIL, cursp());
     952          }
     953          else {
     954            genop_2(s, OP_ARRAY, cursp(), n);
     955          }
    819956          push();
    820957          codegen(s, t->car, VAL);
    821958          pop(); pop();
    822959          if (is_splat) {
    823             genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
     960            genop_1(s, OP_ARYCAT, cursp());
    824961          }
    825962          else {
    826             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
     963            genop_1(s, OP_ARYPUSH, cursp());
    827964          }
    828965        }
     
    832969          codegen(s, t->car, VAL);
    833970          pop(); pop();
    834           if ((intptr_t)t->car->car == NODE_SPLAT) {
    835             genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
     971          if (nint(t->car->car) == NODE_SPLAT) {
     972            genop_1(s, OP_ARYCAT, cursp());
    836973          }
    837974          else {
    838             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
     975            genop_1(s, OP_ARYPUSH, cursp());
    839976          }
    840977          t = t->cdr;
     
    860997gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
    861998{
    862   mrb_sym sym = name ? name : sym(tree->cdr->car);
    863   int idx, skip = 0;
     999  mrb_sym sym = name ? name : nsym(tree->cdr->car);
     1000  int skip = 0;
    8641001  int n = 0, noop = 0, sendv = 0, blk = 0;
    8651002
     
    8671004  if (safe) {
    8681005    int recv = cursp()-1;
    869     genop(s, MKOP_A(OP_LOADNIL, cursp()));
    870     push();
    871     genop(s, MKOP_AB(OP_MOVE, cursp(), recv));
    872     push(); pop();              /* space for a block */
    873     pop();
    874     idx = new_msym(s, mrb_intern_lit(s->mrb, "=="));
    875     genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1));
    876     skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
    877   }
    878   idx = new_msym(s, sym);
     1006    gen_move(s, cursp(), recv, 1);
     1007    skip = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
     1008  }
    8791009  tree = tree->cdr->cdr->car;
    8801010  if (tree) {
     
    8851015    }
    8861016  }
    887   if (sp) {
     1017  if (sp) {                     /* last argument pushed (attr=) */
    8881018    if (sendv) {
     1019      gen_move(s, cursp(), sp, 0);
    8891020      pop();
    890       genop(s, MKOP_AB(OP_ARYPUSH, cursp(), sp));
     1021      genop_1(s, OP_ARYPUSH, cursp());
    8911022      push();
    8921023    }
    8931024    else {
    894       genop(s, MKOP_AB(OP_MOVE, cursp(), sp));
     1025      gen_move(s, cursp(), sp, 0);
    8951026      push();
    8961027      n++;
     
    9011032    codegen(s, tree->cdr, VAL);
    9021033    pop();
    903   }
    904   else {
    905     blk = cursp();
     1034    blk = 1;
    9061035  }
    9071036  push();pop();
     
    9091038  {
    9101039    mrb_int symlen;
    911     const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen);
     1040    const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen);
    9121041
    9131042    if (!noop && symlen == 1 && symname[0] == '+' && n == 1)  {
    914       genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val);
     1043      gen_addsub(s, OP_ADD, cursp());
    9151044    }
    9161045    else if (!noop && symlen == 1 && symname[0] == '-' && n == 1)  {
    917       genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val);
     1046      gen_addsub(s, OP_SUB, cursp());
    9181047    }
    9191048    else if (!noop && symlen == 1 && symname[0] == '*' && n == 1)  {
    920       genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n));
     1049      genop_1(s, OP_MUL, cursp());
    9211050    }
    9221051    else if (!noop && symlen == 1 && symname[0] == '/' && n == 1)  {
    923       genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n));
     1052      genop_1(s, OP_DIV, cursp());
    9241053    }
    9251054    else if (!noop && symlen == 1 && symname[0] == '<' && n == 1)  {
    926       genop(s, MKOP_ABC(OP_LT, cursp(), idx, n));
     1055      genop_1(s, OP_LT, cursp());
    9271056    }
    9281057    else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1)  {
    929       genop(s, MKOP_ABC(OP_LE, cursp(), idx, n));
     1058      genop_1(s, OP_LE, cursp());
    9301059    }
    9311060    else if (!noop && symlen == 1 && symname[0] == '>' && n == 1)  {
    932       genop(s, MKOP_ABC(OP_GT, cursp(), idx, n));
     1061      genop_1(s, OP_GT, cursp());
    9331062    }
    9341063    else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1)  {
    935       genop(s, MKOP_ABC(OP_GE, cursp(), idx, n));
     1064      genop_1(s, OP_GE, cursp());
    9361065    }
    9371066    else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1)  {
    938       genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n));
     1067      genop_1(s, OP_EQ, cursp());
    9391068    }
    9401069    else {
    941       if (sendv) n = CALL_MAXARGS;
    942       if (blk > 0) {                   /* no block */
    943         genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
     1070      int idx = new_sym(s, sym);
     1071
     1072      if (sendv) {
     1073        genop_2(s, blk ? OP_SENDVB : OP_SENDV, cursp(), idx);
    9441074      }
    9451075      else {
    946         genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n));
     1076        genop_3(s, blk ? OP_SENDB : OP_SEND, cursp(), idx, n);
    9471077      }
    9481078    }
     
    9601090{
    9611091  int idx;
    962   int type = (intptr_t)tree->car;
     1092  int type = nint(tree->car);
    9631093
    9641094  tree = tree->cdr;
    9651095  switch (type) {
    9661096  case NODE_GVAR:
    967     idx = new_sym(s, sym(tree));
    968     genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val);
    969     break;
     1097    idx = new_sym(s, nsym(tree));
     1098    genop_2(s, OP_SETGV, sp, idx);
     1099    break;
     1100  case NODE_ARG:
    9701101  case NODE_LVAR:
    971     idx = lv_idx(s, sym(tree));
     1102    idx = lv_idx(s, nsym(tree));
    9721103    if (idx > 0) {
    9731104      if (idx != sp) {
    974         genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val);
     1105        gen_move(s, idx, sp, val);
     1106        if (val && on_eval(s)) genop_0(s, OP_NOP);
    9751107      }
    9761108      break;
     
    9811113
    9821114      while (up) {
    983         idx = lv_idx(up, sym(tree));
     1115        idx = lv_idx(up, nsym(tree));
    9841116        if (idx > 0) {
    985           genop_peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val);
     1117          genop_3(s, OP_SETUPVAR, sp, idx, lv);
    9861118          break;
    9871119        }
     
    9911123    }
    9921124    break;
     1125  case NODE_NVAR:
     1126    idx = nint(tree);
     1127    codegen_error(s, "Can't assign to numbered parameter");
     1128    break;
    9931129  case NODE_IVAR:
    994     idx = new_sym(s, sym(tree));
    995     genop_peep(s, MKOP_ABx(OP_SETIV, sp, idx), val);
     1130    idx = new_sym(s, nsym(tree));
     1131    genop_2(s, OP_SETIV, sp, idx);
    9961132    break;
    9971133  case NODE_CVAR:
    998     idx = new_sym(s, sym(tree));
    999     genop_peep(s, MKOP_ABx(OP_SETCV, sp, idx), val);
     1134    idx = new_sym(s, nsym(tree));
     1135    genop_2(s, OP_SETCV, sp, idx);
    10001136    break;
    10011137  case NODE_CONST:
    1002     idx = new_sym(s, sym(tree));
    1003     genop_peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val);
     1138    idx = new_sym(s, nsym(tree));
     1139    genop_2(s, OP_SETCONST, sp, idx);
    10041140    break;
    10051141  case NODE_COLON2:
    1006     idx = new_sym(s, sym(tree->cdr));
    1007     genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL);
     1142    gen_move(s, cursp(), sp, 0);
    10081143    push();
    10091144    codegen(s, tree->car, VAL);
    10101145    pop_n(2);
    1011     genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val);
     1146    idx = new_sym(s, nsym(tree->cdr));
     1147    genop_2(s, OP_SETMCNST, sp, idx);
    10121148    break;
    10131149
     
    10151151  case NODE_SCALL:
    10161152    push();
    1017     gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL,
     1153    gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL,
    10181154             type == NODE_SCALL);
    10191155    pop();
    10201156    if (val) {
    1021       genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);
     1157      gen_move(s, cursp(), sp, 0);
    10221158    }
    10231159    break;
     
    10501186    n = 0;
    10511187    while (t) {
    1052       genop(s, MKOP_ABC(OP_AREF, cursp(), rhs, n));
    1053       gen_assignment(s, t->car, cursp(), NOVAL);
     1188      int sp = cursp();
     1189
     1190      genop_3(s, OP_AREF, sp, rhs, n);
     1191      push();
     1192      gen_assignment(s, t->car, sp, NOVAL);
     1193      pop();
    10541194      n++;
    10551195      t = t->cdr;
     
    10651205      }
    10661206    }
    1067     if (val) {
    1068       genop(s, MKOP_AB(OP_MOVE, cursp(), rhs));
    1069     }
    1070     else {
    1071       pop();
    1072     }
    1073     push_n(post);
    1074     pop_n(post);
    1075     genop(s, MKOP_ABC(OP_APOST, cursp(), n, post));
     1207    gen_move(s, cursp(), rhs, val);
     1208    push_n(post+1);
     1209    pop_n(post+1);
     1210    genop_3(s, OP_APOST, cursp(), n, post);
    10761211    n = 1;
    1077     if (t->car) {              /* rest */
     1212    if (t->car && t->car != (node*)-1) { /* rest */
    10781213      gen_assignment(s, t->car, cursp(), NOVAL);
    10791214    }
     
    10861221      }
    10871222    }
    1088     if (!val) {
    1089       push();
     1223    if (val) {
     1224      gen_move(s, cursp(), rhs, 0);
    10901225    }
    10911226  }
     
    10931228
    10941229static void
    1095 gen_send_intern(codegen_scope *s)
     1230gen_intern(codegen_scope *s)
    10961231{
    10971232  pop();
    1098   genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "intern")), 0));
     1233  genop_1(s, OP_INTERN, cursp());
    10991234  push();
    11001235}
     1236
    11011237static void
    11021238gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val)
     
    11061242
    11071243    while (tree) {
    1108       switch ((intptr_t)tree->car->car) {
     1244      switch (nint(tree->car->car)) {
    11091245      case NODE_STR:
    1110         if ((tree->cdr == NULL) && ((intptr_t)tree->car->cdr->cdr == 0))
     1246        if ((tree->cdr == NULL) && (nint(tree->car->cdr->cdr) == 0))
    11111247          break;
    11121248        /* fall through */
     
    11211257          ++i;
    11221258          if (sym)
    1123             gen_send_intern(s);
     1259            gen_intern(s);
    11241260        }
    11251261        break;
    11261262      }
    1127       if (j >= 2) {
     1263      while (j >= 2) {
    11281264        pop(); pop();
    1129         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     1265        genop_1(s, OP_STRCAT, cursp());
    11301266        push();
    1131         j = 1;
     1267        j--;
    11321268      }
    11331269      tree = tree->cdr;
     
    11361272      ++i;
    11371273      if (sym)
    1138         gen_send_intern(s);
     1274        gen_intern(s);
    11391275    }
    11401276    pop_n(i);
    1141     genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));
     1277    genop_2(s, OP_ARRAY, cursp(), i);
    11421278    push();
    11431279  }
    11441280  else {
    11451281    while (tree) {
    1146       switch ((intptr_t)tree->car->car) {
     1282      switch (nint(tree->car->car)) {
    11471283      case NODE_BEGIN: case NODE_BLOCK:
    11481284        codegen(s, tree->car, NOVAL);
     
    11581294  int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg));
    11591295
    1160   genop(s, MKOP_ABx(OP_ERR, 1, idx));
    1161 }
    1162 
     1296  genop_1(s, OP_ERR, idx);
     1297}
     1298
     1299#ifndef MRB_WITHOUT_FLOAT
    11631300static double
    11641301readint_float(codegen_scope *s, const char *p, int base)
     
    11861323  return f;
    11871324}
     1325#endif
    11881326
    11891327static mrb_int
     
    12331371gen_retval(codegen_scope *s, node *tree)
    12341372{
    1235   if ((intptr_t)tree->car == NODE_SPLAT) {
    1236     genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), 0));
    1237     push();
     1373  if (nint(tree->car) == NODE_SPLAT) {
    12381374    codegen(s, tree, VAL);
    1239     pop(); pop();
    1240     genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
     1375    pop();
     1376    genop_1(s, OP_ARYDUP, cursp());
    12411377  }
    12421378  else {
     
    12541390  if (!tree) {
    12551391    if (val) {
    1256       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1392      genop_1(s, OP_LOADNIL, cursp());
    12571393      push();
    12581394    }
     
    12651401  }
    12661402  if (s->irep && s->filename_index != tree->filename_index) {
    1267     s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);
    1268     mrb_debug_info_append_file(s->mrb, s->irep, s->debug_start_pos, s->pc);
     1403    mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
     1404    const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
     1405
     1406    mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
     1407                               filename, s->lines, s->debug_start_pos, s->pc);
    12691408    s->debug_start_pos = s->pc;
    12701409    s->filename_index = tree->filename_index;
    1271     s->filename = mrb_parser_get_filename(s->parser, tree->filename_index);
    1272   }
    1273 
    1274   nt = (intptr_t)tree->car;
     1410    s->filename_sym = mrb_parser_get_filename(s->parser, tree->filename_index);
     1411  }
     1412
     1413  nt = nint(tree->car);
    12751414  s->lineno = tree->lineno;
    12761415  tree = tree->cdr;
     
    12781417  case NODE_BEGIN:
    12791418    if (val && !tree) {
    1280       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1419      genop_1(s, OP_LOADNIL, cursp());
    12811420      push();
    12821421    }
     
    12891428  case NODE_RESCUE:
    12901429    {
    1291       int onerr, noexc, exend, pos1, pos2, tmp;
     1430      int noexc, exend, pos1, pos2, tmp;
    12921431      struct loopinfo *lp;
    12931432
    12941433      if (tree->car == NULL) goto exit;
    1295       onerr = genop(s, MKOP_Bx(OP_ONERR, 0));
    12961434      lp = loop_push(s, LOOP_BEGIN);
    1297       lp->pc1 = onerr;
     1435      lp->pc0 = new_label(s);
     1436      lp->pc1 = genjmp(s, OP_ONERR, 0);
    12981437      codegen(s, tree->car, VAL);
    12991438      pop();
    13001439      lp->type = LOOP_RESCUE;
    1301       noexc = genop(s, MKOP_Bx(OP_JMP, 0));
    1302       dispatch(s, onerr);
     1440      noexc = genjmp(s, OP_JMP, 0);
     1441      dispatch(s, lp->pc1);
    13031442      tree = tree->cdr;
    13041443      exend = 0;
     
    13081447        int exc = cursp();
    13091448
    1310         genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0));
     1449        genop_1(s, OP_EXCEPT, exc);
    13111450        push();
    13121451        while (n2) {
     
    13171456          pos2 = 0;
    13181457          do {
    1319             if (n4 && n4->car && (intptr_t)n4->car->car == NODE_SPLAT) {
     1458            if (n4 && n4->car && nint(n4->car->car) == NODE_SPLAT) {
    13201459              codegen(s, n4->car, VAL);
    1321               genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
     1460              gen_move(s, cursp(), exc, 0);
     1461              push_n(2); pop_n(2); /* space for one arg and a block */
    13221462              pop();
    1323               genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
     1463              genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1);
    13241464            }
    13251465            else {
     
    13281468              }
    13291469              else {
    1330                 genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError"))));
     1470                genop_2(s, OP_GETCONST, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "StandardError")));
    13311471                push();
    13321472              }
    13331473              pop();
    1334               genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1));
     1474              genop_2(s, OP_RESCUE, exc, cursp());
    13351475            }
    1336             tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
     1476            tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, val);
    13371477            pos2 = tmp;
    13381478            if (n4) {
     
    13401480            }
    13411481          } while (n4);
    1342           pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1482          pos1 = genjmp(s, OP_JMP, 0);
    13431483          dispatch_linked(s, pos2);
    13441484
     
    13511491            if (val) pop();
    13521492          }
    1353           tmp = genop(s, MKOP_sBx(OP_JMP, exend));
     1493          tmp = genjmp(s, OP_JMP, exend);
    13541494          exend = tmp;
    13551495          n2 = n2->cdr;
     
    13581498        if (pos1) {
    13591499          dispatch(s, pos1);
    1360           genop(s, MKOP_A(OP_RAISE, exc));
     1500          genop_1(s, OP_RAISE, exc);
    13611501        }
    13621502      }
     
    13641504      tree = tree->cdr;
    13651505      dispatch(s, noexc);
    1366       genop(s, MKOP_A(OP_POPERR, 1));
     1506      genop_1(s, OP_POPERR, 1);
    13671507      if (tree->car) {
    13681508        codegen(s, tree->car, val);
     
    13781518  case NODE_ENSURE:
    13791519    if (!tree->cdr || !tree->cdr->cdr ||
    1380         ((intptr_t)tree->cdr->cdr->car == NODE_BEGIN &&
     1520        (nint(tree->cdr->cdr->car) == NODE_BEGIN &&
    13811521         tree->cdr->cdr->cdr)) {
    13821522      int idx;
    1383       int epush = s->pc;
    1384 
    1385       genop(s, MKOP_Bx(OP_EPUSH, 0));
     1523
    13861524      s->ensure_level++;
     1525      idx = scope_body(s, tree->cdr, NOVAL);
     1526      genop_1(s, OP_EPUSH, idx);
    13871527      codegen(s, tree->car, val);
    1388       idx = scope_body(s, tree->cdr, NOVAL);
    1389       s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx);
    13901528      s->ensure_level--;
    1391       genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL);
     1529      genop_1(s, OP_EPOP, 1);
    13921530    }
    13931531    else {                      /* empty ensure ignored */
     
    14001538      int idx = lambda_body(s, tree, 1);
    14011539
    1402       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_LAMBDA));
     1540      genop_2(s, OP_LAMBDA, cursp(), idx);
    14031541      push();
    14041542    }
     
    14091547      int idx = lambda_body(s, tree, 1);
    14101548
    1411       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_BLOCK));
     1549      genop_2(s, OP_BLOCK, cursp(), idx);
    14121550      push();
    14131551    }
     
    14161554  case NODE_IF:
    14171555    {
    1418       int pos1, pos2;
    1419       node *e = tree->cdr->cdr->car;
     1556      int pos1, pos2, nil_p = FALSE;
     1557      node *elsepart = tree->cdr->cdr->car;
    14201558
    14211559      if (!tree->car) {
    1422         codegen(s, e, val);
     1560        codegen(s, elsepart, val);
    14231561        goto exit;
    14241562      }
    1425       switch ((intptr_t)tree->car->car) {
     1563      switch (nint(tree->car->car)) {
    14261564      case NODE_TRUE:
    14271565      case NODE_INT:
     
    14311569      case NODE_FALSE:
    14321570      case NODE_NIL:
    1433         codegen(s, e, val);
     1571        codegen(s, elsepart, val);
    14341572        goto exit;
    1435       }
    1436       codegen(s, tree->car, VAL);
     1573      case NODE_CALL:
     1574        {
     1575          node *n = tree->car->cdr;
     1576          mrb_sym mid = nsym(n->cdr->car);
     1577          mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?");
     1578          if (mid == mnil && n->cdr->cdr->car == NULL) {
     1579            nil_p = TRUE;
     1580            codegen(s, n->car, VAL);
     1581          }
     1582        }
     1583        break;
     1584      }
     1585      if (!nil_p) {
     1586        codegen(s, tree->car, VAL);
     1587      }
    14371588      pop();
    1438       pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL);
    1439 
    1440       codegen(s, tree->cdr->car, val);
    1441       if (e) {
     1589      if (val || tree->cdr->car) {
     1590        if (nil_p) {
     1591          pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
     1592          pos1 = genjmp(s, OP_JMP, 0);
     1593          dispatch(s, pos2);
     1594        }
     1595        else {
     1596          pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
     1597        }
     1598        codegen(s, tree->cdr->car, val);
    14421599        if (val) pop();
    1443         pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
    1444         dispatch(s, pos1);
    1445         codegen(s, e, val);
    1446         dispatch(s, pos2);
    1447       }
    1448       else {
    1449         if (val) {
    1450           pop();
    1451           pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
     1600        if (elsepart || val) {
     1601          pos2 = genjmp(s, OP_JMP, 0);
    14521602          dispatch(s, pos1);
    1453           genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1603          codegen(s, elsepart, val);
    14541604          dispatch(s, pos2);
    1455           push();
    14561605        }
    14571606        else {
    14581607          dispatch(s, pos1);
     1608        }
     1609      }
     1610      else {                    /* empty then-part */
     1611        if (elsepart) {
     1612          if (nil_p) {
     1613            pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
     1614          }
     1615          else {
     1616            pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val);
     1617          }
     1618          codegen(s, elsepart, val);
     1619          dispatch(s, pos1);
     1620        }
     1621        else if (val && !nil_p) {
     1622          genop_1(s, OP_LOADNIL, cursp());
     1623          push();
    14591624        }
    14601625      }
     
    14681633      codegen(s, tree->car, VAL);
    14691634      pop();
    1470       pos = genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
     1635      pos = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
    14711636      codegen(s, tree->cdr, val);
    14721637      dispatch(s, pos);
     
    14801645      codegen(s, tree->car, VAL);
    14811646      pop();
    1482       pos = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
     1647      pos = genjmp2(s, OP_JMPIF, cursp(), 0, val);
    14831648      codegen(s, tree->cdr, val);
    14841649      dispatch(s, pos);
     
    14901655      struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
    14911656
    1492       lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1657      lp->pc0 = new_label(s);
     1658      lp->pc1 = genjmp(s, OP_JMP, 0);
    14931659      lp->pc2 = new_label(s);
    14941660      codegen(s, tree->cdr, NOVAL);
     
    14961662      codegen(s, tree->car, VAL);
    14971663      pop();
    1498       genop(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));
     1664      genjmp2(s, OP_JMPIF, cursp(), lp->pc2, NOVAL);
    14991665
    15001666      loop_pop(s, val);
     
    15061672      struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
    15071673
    1508       lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1674      lp->pc0 = new_label(s);
     1675      lp->pc1 = genjmp(s, OP_JMP, 0);
    15091676      lp->pc2 = new_label(s);
    15101677      codegen(s, tree->cdr, NOVAL);
     
    15121679      codegen(s, tree->car, VAL);
    15131680      pop();
    1514       genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));
     1681      genjmp2(s, OP_JMPNOT, cursp(), lp->pc2, NOVAL);
    15151682
    15161683      loop_pop(s, val);
     
    15411708          codegen(s, n->car, VAL);
    15421709          if (head) {
    1543             genop(s, MKOP_AB(OP_MOVE, cursp(), head));
    1544             pop();
    1545             if ((intptr_t)n->car->car == NODE_SPLAT) {
    1546               genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
     1710            gen_move(s, cursp(), head, 0);
     1711            push(); push(); pop(); pop(); pop();
     1712            if (nint(n->car->car) == NODE_SPLAT) {
     1713              genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1);
    15471714            }
    15481715            else {
    1549               genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1));
     1716              genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "===")), 1);
    15501717            }
    15511718          }
     
    15531720            pop();
    15541721          }
    1555           tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
     1722          tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, NOVAL);
    15561723          pos2 = tmp;
    15571724          n = n->cdr;
    15581725        }
    15591726        if (tree->car->car) {
    1560           pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1727          pos1 = genjmp(s, OP_JMP, 0);
    15611728          dispatch_linked(s, pos2);
    15621729        }
    15631730        codegen(s, tree->car->cdr, val);
    15641731        if (val) pop();
    1565         tmp = genop(s, MKOP_sBx(OP_JMP, pos3));
     1732        tmp = genjmp(s, OP_JMP, pos3);
    15661733        pos3 = tmp;
    15671734        if (pos1) dispatch(s, pos1);
     
    15701737      if (val) {
    15711738        int pos = cursp();
    1572         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1739        genop_1(s, OP_LOADNIL, cursp());
    15731740        if (pos3) dispatch_linked(s, pos3);
    15741741        if (head) pop();
    15751742        if (cursp() != pos) {
    1576           genop(s, MKOP_AB(OP_MOVE, cursp(), pos));
     1743          gen_move(s, cursp(), pos, 0);
    15771744        }
    15781745        push();
     
    16061773    if (val) {
    16071774      pop(); pop();
    1608       genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE));
     1775      genop_1(s, OP_RANGE_INC, cursp());
    16091776      push();
    16101777    }
     
    16161783    if (val) {
    16171784      pop(); pop();
    1618       genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE));
     1785      genop_1(s, OP_RANGE_EXC, cursp());
    16191786      push();
    16201787    }
     
    16231790  case NODE_COLON2:
    16241791    {
    1625       int sym = new_sym(s, sym(tree->cdr));
     1792      int sym = new_sym(s, nsym(tree->cdr));
    16261793
    16271794      codegen(s, tree->car, VAL);
    16281795      pop();
    1629       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     1796      genop_2(s, OP_GETMCNST, cursp(), sym);
    16301797      if (val) push();
    16311798    }
     
    16341801  case NODE_COLON3:
    16351802    {
    1636       int sym = new_sym(s, sym(tree));
    1637 
    1638       genop(s, MKOP_A(OP_OCLASS, cursp()));
    1639       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     1803      int sym = new_sym(s, nsym(tree));
     1804
     1805      genop_1(s, OP_OCLASS, cursp());
     1806      genop_2(s, OP_GETMCNST, cursp(), sym);
    16401807      if (val) push();
    16411808    }
     
    16501817        if (val) {
    16511818          pop_n(n);
    1652           genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
     1819          genop_2(s, OP_ARRAY, cursp(), n);
    16531820          push();
    16541821        }
     
    16611828
    16621829  case NODE_HASH:
     1830  case NODE_KW_HASH:
    16631831    {
    16641832      int len = 0;
     
    16661834
    16671835      while (tree) {
    1668         codegen(s, tree->car->car, val);
    1669         codegen(s, tree->car->cdr, val);
    1670         len++;
     1836        if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) {
     1837          if (len > 0) {
     1838            pop_n(len*2);
     1839            if (!update) {
     1840              genop_2(s, OP_HASH, cursp(), len);
     1841            }
     1842            else {
     1843              pop();
     1844              genop_2(s, OP_HASHADD, cursp(), len);
     1845            }
     1846            push();
     1847          }
     1848          codegen(s, tree->car->cdr, VAL);
     1849          if (len > 0 || update) {
     1850            pop(); pop();
     1851            genop_1(s, OP_HASHCAT, cursp());
     1852            push();
     1853          }
     1854          update = TRUE;
     1855          len = 0;
     1856        }
     1857        else {
     1858          codegen(s, tree->car->car, val);
     1859          codegen(s, tree->car->cdr, val);
     1860          len++;
     1861        }
    16711862        tree = tree->cdr;
    1672         if (val && len == 126) {
     1863        if (val && len == 255) {
    16731864          pop_n(len*2);
    1674           genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
    1675           if (update) {
     1865          if (!update) {
     1866            genop_2(s, OP_HASH, cursp(), len);
     1867          }
     1868          else {
    16761869            pop();
    1677             genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));
     1870            genop_2(s, OP_HASHADD, cursp(), len);
    16781871          }
    16791872          push();
     
    16841877      if (val) {
    16851878        pop_n(len*2);
    1686         genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
    1687         if (update) {
     1879        if (!update) {
     1880          genop_2(s, OP_HASH, cursp(), len);
     1881        }
     1882        else {
    16881883          pop();
    1689           genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));
     1884          if (len > 0) {
     1885            genop_2(s, OP_HASHADD, cursp(), len);
     1886          }
    16901887        }
    16911888        push();
     
    17101907      int rhs = cursp();
    17111908
    1712       if ((intptr_t)t->car == NODE_ARRAY && t->cdr && nosplat(t->cdr)) {
     1909      if (nint(t->car) == NODE_ARRAY && t->cdr && nosplat(t->cdr)) {
    17131910        /* fixed rhs */
    17141911        t = t->cdr;
     
    17281925            }
    17291926            else {
    1730               genop(s, MKOP_A(OP_LOADNIL, rhs+n));
     1927              genop_1(s, OP_LOADNIL, rhs+n);
    17311928              gen_assignment(s, t->car, rhs+n, NOVAL);
    17321929            }
     
    17521949              rn = len - post - n;
    17531950            }
    1754             genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));
     1951            genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn);
    17551952            gen_assignment(s, t->car, cursp(), NOVAL);
    17561953            n += rn;
     
    17671964        pop_n(len);
    17681965        if (val) {
    1769           genop(s, MKOP_ABC(OP_ARRAY, rhs, rhs, len));
     1966          genop_2(s, OP_ARRAY, rhs, len);
    17701967          push();
    17711968        }
     
    17841981  case NODE_OP_ASGN:
    17851982    {
    1786       mrb_sym sym = sym(tree->cdr->car);
     1983      mrb_sym sym = nsym(tree->cdr->car);
    17871984      mrb_int len;
    1788       const char *name = mrb_sym2name_len(s->mrb, sym, &len);
     1985      const char *name = mrb_sym_name_len(s->mrb, sym, &len);
    17891986      int idx, callargs = -1, vsp = -1;
    17901987
    17911988      if ((len == 2 && name[0] == '|' && name[1] == '|') &&
    1792           ((intptr_t)tree->car->car == NODE_CONST ||
    1793            (intptr_t)tree->car->car == NODE_CVAR)) {
     1989          (nint(tree->car->car) == NODE_CONST ||
     1990           nint(tree->car->car) == NODE_CVAR)) {
    17941991        int onerr, noexc, exc;
    17951992        struct loopinfo *lp;
    17961993
    1797         onerr = genop(s, MKOP_Bx(OP_ONERR, 0));
     1994        onerr = genjmp(s, OP_ONERR, 0);
    17981995        lp = loop_push(s, LOOP_BEGIN);
    17991996        lp->pc1 = onerr;
     
    18011998        codegen(s, tree->car, VAL);
    18021999        lp->type = LOOP_RESCUE;
    1803         genop(s, MKOP_A(OP_POPERR, 1));
    1804         noexc = genop(s, MKOP_Bx(OP_JMP, 0));
     2000        genop_1(s, OP_POPERR, 1);
     2001        noexc = genjmp(s, OP_JMP, 0);
    18052002        dispatch(s, onerr);
    1806         genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0));
    1807         genop(s, MKOP_A(OP_LOADF, exc));
     2003        genop_1(s, OP_EXCEPT, exc);
     2004        genop_1(s, OP_LOADF, exc);
    18082005        dispatch(s, noexc);
    18092006        loop_pop(s, NOVAL);
    18102007      }
    1811       else if ((intptr_t)tree->car->car == NODE_CALL) {
     2008      else if (nint(tree->car->car) == NODE_CALL) {
    18122009        node *n = tree->car->cdr;
     2010        int base, i, nargs = 0;
     2011        callargs = 0;
    18132012
    18142013        if (val) {
     
    18172016        }
    18182017        codegen(s, n->car, VAL);   /* receiver */
    1819         idx = new_msym(s, sym(n->cdr->car));
     2018        idx = new_sym(s, nsym(n->cdr->car));
     2019        base = cursp()-1;
    18202020        if (n->cdr->cdr->car) {
    1821           int base = cursp()-1;
    1822           int nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1);
    1823 
    1824           /* copy receiver and arguments */
     2021          nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1);
    18252022          if (nargs >= 0) {
    1826             int i;
    1827 
    1828             genop(s, MKOP_AB(OP_MOVE, cursp(), base));
    1829             for (i=0; i<nargs; i++) {
    1830               genop(s, MKOP_AB(OP_MOVE, cursp()+i+1, base+i+1));
    1831             }
    1832             push_n(nargs+1);
    1833             pop_n(nargs+1);
    18342023            callargs = nargs;
    18352024          }
    1836           else {
    1837             /* varargs */
     2025          else { /* varargs */
    18382026            push();
    1839             genop(s, MKOP_AB(OP_MOVE, cursp(), base));
    1840             genop(s, MKOP_AB(OP_MOVE, cursp()+1, base+1));
     2027            nargs = 1;
    18412028            callargs = CALL_MAXARGS;
    18422029          }
    1843           genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
    1844         }
    1845         else {
    1846           genop(s, MKOP_AB(OP_MOVE, cursp(), cursp()-1));
    1847           genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0));
    1848           callargs = 0;
    1849         }
     2030        }
     2031        /* copy receiver and arguments */
     2032        gen_move(s, cursp(), base, 1);
     2033        for (i=0; i<nargs; i++) {
     2034          gen_move(s, cursp()+i+1, base+i+1, 1);
     2035        }
     2036        push_n(nargs+2);pop_n(nargs+2); /* space for receiver, arguments and a block */
     2037        genop_3(s, OP_SEND, cursp(), idx, callargs);
    18502038        push();
    18512039      }
     
    18612049        if (val) {
    18622050          if (vsp >= 0) {
    1863             genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
    1864           }
    1865           pos = genop(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0));
     2051            gen_move(s, vsp, cursp(), 1);
     2052          }
     2053          pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val);
    18662054        }
    18672055        else {
    1868           pos = genop_peep(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0), NOVAL);
     2056          pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val);
    18692057        }
    18702058        codegen(s, tree->cdr->cdr->car, VAL);
    18712059        pop();
    18722060        if (val && vsp >= 0) {
    1873           genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
    1874         }
    1875         if ((intptr_t)tree->car->car == NODE_CALL) {
    1876           mrb_sym m = sym(tree->car->cdr->cdr->car);
    1877           mrb_sym m2 = attrsym(s, m);
    1878 
    1879           idx = new_msym(s, m2);
    1880           pop();
     2061          gen_move(s, vsp, cursp(), 1);
     2062        }
     2063        if (nint(tree->car->car) == NODE_CALL) {
    18812064          if (callargs == CALL_MAXARGS) {
    1882             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
    18832065            pop();
    1884             genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
     2066            genop_1(s, OP_ARYPUSH, cursp());
    18852067          }
    18862068          else {
    18872069            pop_n(callargs);
    1888             genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs+1));
    1889           }
     2070            callargs++;
     2071          }
     2072          pop();
     2073          idx = new_sym(s, attrsym(s, nsym(tree->car->cdr->cdr->car)));
     2074          genop_3(s, OP_SEND, cursp(), idx, callargs);
    18902075        }
    18912076        else {
     
    18992084      pop(); pop();
    19002085
    1901       idx = new_msym(s, sym);
    19022086      if (len == 1 && name[0] == '+')  {
    1903         genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, 1), val);
     2087        gen_addsub(s, OP_ADD, cursp());
    19042088      }
    19052089      else if (len == 1 && name[0] == '-')  {
    1906         genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, 1), val);
     2090        gen_addsub(s, OP_SUB, cursp());
    19072091      }
    19082092      else if (len == 1 && name[0] == '*')  {
    1909         genop(s, MKOP_ABC(OP_MUL, cursp(), idx, 1));
     2093        genop_1(s, OP_MUL, cursp());
    19102094      }
    19112095      else if (len == 1 && name[0] == '/')  {
    1912         genop(s, MKOP_ABC(OP_DIV, cursp(), idx, 1));
     2096        genop_1(s, OP_DIV, cursp());
    19132097      }
    19142098      else if (len == 1 && name[0] == '<')  {
    1915         genop(s, MKOP_ABC(OP_LT, cursp(), idx, 1));
     2099        genop_1(s, OP_LT, cursp());
    19162100      }
    19172101      else if (len == 2 && name[0] == '<' && name[1] == '=')  {
    1918         genop(s, MKOP_ABC(OP_LE, cursp(), idx, 1));
     2102        genop_1(s, OP_LE, cursp());
    19192103      }
    19202104      else if (len == 1 && name[0] == '>')  {
    1921         genop(s, MKOP_ABC(OP_GT, cursp(), idx, 1));
     2105        genop_1(s, OP_GT, cursp());
    19222106      }
    19232107      else if (len == 2 && name[0] == '>' && name[1] == '=')  {
    1924         genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1));
     2108        genop_1(s, OP_GE, cursp());
    19252109      }
    19262110      else {
    1927         genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
     2111        idx = new_sym(s, sym);
     2112        genop_3(s, OP_SEND, cursp(), idx, 1);
    19282113      }
    19292114      if (callargs < 0) {
     
    19322117      else {
    19332118        if (val && vsp >= 0) {
    1934           genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
     2119          gen_move(s, vsp, cursp(), 0);
    19352120        }
    19362121        if (callargs == CALL_MAXARGS) {
    19372122          pop();
    1938           genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
     2123          genop_1(s, OP_ARYPUSH, cursp());
    19392124        }
    19402125        else {
     
    19432128        }
    19442129        pop();
    1945         idx = new_msym(s, attrsym(s,sym(tree->car->cdr->cdr->car)));
    1946         genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
     2130        idx = new_sym(s, attrsym(s,nsym(tree->car->cdr->cdr->car)));
     2131        genop_3(s, OP_SEND, cursp(), idx, callargs);
    19472132      }
    19482133    }
     
    19612146        if (!s2) break;
    19622147      }
    1963       genop(s, MKOP_ABx(OP_ARGARY, cursp(), (lv & 0xf)));
     2148      genop_2S(s, OP_ARGARY, cursp(), (lv & 0xf));
    19642149      push(); push();         /* ARGARY pushes two values */
    19652150      pop(); pop();
     
    19792164      }
    19802165      else {
    1981         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2166        genop_1(s, OP_LOADNIL, cursp());
    19822167        push(); pop();
    19832168      }
    19842169      pop_n(n+1);
    19852170      if (sendv) n = CALL_MAXARGS;
    1986       genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, n));
     2171      genop_2(s, OP_SUPER, cursp(), n);
    19872172      if (val) push();
    19882173    }
     
    20012186      }
    20022187      if (s2) ainfo = s2->ainfo;
    2003       genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));
     2188      genop_2S(s, OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf));
    20042189      push(); push(); pop();    /* ARGARY pushes two values */
    20052190      if (tree && tree->cdr) {
     
    20082193      }
    20092194      pop(); pop();
    2010       genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));
     2195      genop_2(s, OP_SUPER, cursp(), CALL_MAXARGS);
    20112196      if (val) push();
    20122197    }
     
    20182203    }
    20192204    else {
    2020       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2205      genop_1(s, OP_LOADNIL, cursp());
    20212206    }
    20222207    if (s->loop) {
    2023       genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));
     2208      gen_return(s, OP_RETURN_BLK, cursp());
    20242209    }
    20252210    else {
    2026       genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
     2211      gen_return(s, OP_RETURN, cursp());
    20272212    }
    20282213    if (val) push();
     
    20492234        }
    20502235      }
     2236      push();pop(); /* space for a block */
    20512237      pop_n(n+1);
    2052       genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));
     2238      genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf));
    20532239      if (sendv) n = CALL_MAXARGS;
    2054       genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n));
     2240      genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "call")), n);
    20552241      if (val) push();
    20562242    }
     
    20682254    else if (s->loop->type == LOOP_NORMAL) {
    20692255      if (s->ensure_level > s->loop->ensure_level) {
    2070         genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
     2256        genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
    20712257      }
    20722258      codegen(s, tree, NOVAL);
    2073       genop(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc));
     2259      genjmp(s, OP_JMP, s->loop->pc0);
    20742260    }
    20752261    else {
     
    20792265      }
    20802266      else {
    2081         genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2082       }
    2083       genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
     2267        genop_1(s, OP_LOADNIL, cursp());
     2268      }
     2269      gen_return(s, OP_RETURN, cursp());
    20842270    }
    20852271    if (val) push();
     
    20922278    else {
    20932279      if (s->ensure_level > s->loop->ensure_level) {
    2094         genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
    2095       }
    2096       genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc));
     2280        genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
     2281      }
     2282      genjmp(s, OP_JMP, s->loop->pc2);
    20972283    }
    20982284    if (val) push();
     
    21212307        else {
    21222308          if (n > 0) {
    2123             while (n--) {
    2124               genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
    2125             }
     2309            genop_1(s, OP_POPERR, n);
    21262310          }
    21272311          if (s->ensure_level > lp->ensure_level) {
    2128             genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL);
    2129           }
    2130           genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));
     2312            genop_1(s, OP_EPOP, s->ensure_level - lp->ensure_level);
     2313          }
     2314          genjmp(s, OP_JMP, lp->pc0);
    21312315        }
    21322316      }
     
    21372321  case NODE_LVAR:
    21382322    if (val) {
    2139       int idx = lv_idx(s, sym(tree));
     2323      int idx = lv_idx(s, nsym(tree));
    21402324
    21412325      if (idx > 0) {
    2142         genop_peep(s, MKOP_AB(OP_MOVE, cursp(), idx), NOVAL);
     2326        gen_move(s, cursp(), idx, val);
     2327        if (val && on_eval(s)) genop_0(s, OP_NOP);
    21432328      }
    21442329      else {
     
    21472332
    21482333        while (up) {
    2149           idx = lv_idx(up, sym(tree));
     2334          idx = lv_idx(up, nsym(tree));
    21502335          if (idx > 0) {
    2151             genop(s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv));
     2336            genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
    21522337            break;
    21532338          }
     
    21602345    break;
    21612346
     2347  case NODE_NVAR:
     2348    if (val) {
     2349      int idx = nint(tree);
     2350
     2351      gen_move(s, cursp(), idx, val);
     2352      if (val && on_eval(s)) genop_0(s, OP_NOP);
     2353
     2354      push();
     2355    }
     2356    break;
     2357
    21622358  case NODE_GVAR:
    2163     if (val) {
    2164       int sym = new_sym(s, sym(tree));
    2165 
    2166       genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
    2167       push();
     2359    {
     2360      int sym = new_sym(s, nsym(tree));
     2361
     2362      genop_2(s, OP_GETGV, cursp(), sym);
     2363      if (val) push();
    21682364    }
    21692365    break;
    21702366
    21712367  case NODE_IVAR:
    2172     if (val) {
    2173       int sym = new_sym(s, sym(tree));
    2174 
    2175       genop(s, MKOP_ABx(OP_GETIV, cursp(), sym));
    2176       push();
     2368    {
     2369      int sym = new_sym(s, nsym(tree));
     2370
     2371      genop_2(s, OP_GETIV, cursp(), sym);
     2372      if (val) push();
    21772373    }
    21782374    break;
    21792375
    21802376  case NODE_CVAR:
    2181     if (val) {
    2182       int sym = new_sym(s, sym(tree));
    2183 
    2184       genop(s, MKOP_ABx(OP_GETCV, cursp(), sym));
    2185       push();
     2377    {
     2378      int sym = new_sym(s, nsym(tree));
     2379
     2380      genop_2(s, OP_GETCV, cursp(), sym);
     2381      if (val) push();
    21862382    }
    21872383    break;
     
    21892385  case NODE_CONST:
    21902386    {
    2191       int sym = new_sym(s, sym(tree));
    2192 
    2193       genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym));
    2194       if (val) {
    2195         push();
    2196       }
    2197     }
    2198     break;
    2199 
    2200   case NODE_DEFINED:
    2201     codegen(s, tree, VAL);
     2387      int sym = new_sym(s, nsym(tree));
     2388
     2389      genop_2(s, OP_GETCONST, cursp(), sym);
     2390      if (val) push();
     2391    }
    22022392    break;
    22032393
    22042394  case NODE_BACK_REF:
    22052395    if (val) {
    2206       char buf[3];
    2207       int sym;
    2208 
    2209       buf[0] = '$';
    2210       buf[1] = (char)(intptr_t)tree;
    2211       buf[2] = 0;
    2212       sym = new_sym(s, mrb_intern_cstr(s->mrb, buf));
    2213       genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
     2396      char buf[] = {'$', nchar(tree)};
     2397      int sym = new_sym(s, mrb_intern(s->mrb, buf, sizeof(buf)));
     2398
     2399      genop_2(s, OP_GETGV, cursp(), sym);
    22142400      push();
    22152401    }
     
    22222408      int sym;
    22232409
    2224       str = mrb_format(mrb, "$%S", mrb_fixnum_value((mrb_int)(intptr_t)tree));
     2410      str = mrb_format(mrb, "$%d", nint(tree));
    22252411      sym = new_sym(s, mrb_intern_str(mrb, str));
    2226       genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
     2412      genop_2(s, OP_GETGV, cursp(), sym);
    22272413      push();
    22282414    }
     
    22342420
    22352421  case NODE_BLOCK_ARG:
    2236     codegen(s, tree, VAL);
     2422    codegen(s, tree, val);
    22372423    break;
    22382424
     
    22402426    if (val) {
    22412427      char *p = (char*)tree->car;
    2242       int base = (intptr_t)tree->cdr->car;
     2428      int base = nint(tree->cdr->car);
    22432429      mrb_int i;
    2244       mrb_code co;
    22452430      mrb_bool overflow;
    22462431
    22472432      i = readint_mrb_int(s, p, base, FALSE, &overflow);
     2433#ifndef MRB_WITHOUT_FLOAT
    22482434      if (overflow) {
    22492435        double f = readint_float(s, p, base);
    22502436        int off = new_lit(s, mrb_float_value(s->mrb, f));
    22512437
    2252         genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
    2253       }
    2254       else {
    2255         if (i < MAXARG_sBx && i > -MAXARG_sBx) {
    2256           co = MKOP_AsBx(OP_LOADI, cursp(), i);
    2257         }
     2438        genop_2(s, OP_LOADL, cursp(), off);
     2439      }
     2440      else
     2441#endif
     2442      {
     2443        if (i == -1) genop_1(s, OP_LOADI__1, cursp());
     2444        else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
     2445        else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp());
     2446        else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i);
    22582447        else {
    22592448          int off = new_lit(s, mrb_fixnum_value(i));
    2260           co = MKOP_ABx(OP_LOADL, cursp(), off);
    2261         }
    2262         genop(s, co);
     2449          genop_2(s, OP_LOADL, cursp(), off);
     2450        }
    22632451      }
    22642452      push();
     
    22662454    break;
    22672455
     2456#ifndef MRB_WITHOUT_FLOAT
    22682457  case NODE_FLOAT:
    22692458    if (val) {
     
    22722461      int off = new_lit(s, mrb_float_value(s->mrb, f));
    22732462
    2274       genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
     2463      genop_2(s, OP_LOADL, cursp(), off);
    22752464      push();
    22762465    }
    22772466    break;
     2467#endif
    22782468
    22792469  case NODE_NEGATE:
    22802470    {
    2281       nt = (intptr_t)tree->car;
    2282       tree = tree->cdr;
     2471      nt = nint(tree->car);
    22832472      switch (nt) {
     2473#ifndef MRB_WITHOUT_FLOAT
    22842474      case NODE_FLOAT:
    22852475        if (val) {
    2286           char *p = (char*)tree;
     2476          char *p = (char*)tree->cdr;
    22872477          mrb_float f = mrb_float_read(p, NULL);
    22882478          int off = new_lit(s, mrb_float_value(s->mrb, -f));
    22892479
    2290           genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
     2480          genop_2(s, OP_LOADL, cursp(), off);
    22912481          push();
    22922482        }
    22932483        break;
     2484#endif
    22942485
    22952486      case NODE_INT:
    22962487        if (val) {
    2297           char *p = (char*)tree->car;
    2298           int base = (intptr_t)tree->cdr->car;
     2488          char *p = (char*)tree->cdr->car;
     2489          int base = nint(tree->cdr->cdr->car);
    22992490          mrb_int i;
    2300           mrb_code co;
    23012491          mrb_bool overflow;
    23022492
    23032493          i = readint_mrb_int(s, p, base, TRUE, &overflow);
     2494#ifndef MRB_WITHOUT_FLOAT
    23042495          if (overflow) {
    23052496            double f = readint_float(s, p, base);
    23062497            int off = new_lit(s, mrb_float_value(s->mrb, -f));
    23072498
    2308             genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
     2499            genop_2(s, OP_LOADL, cursp(), off);
    23092500          }
    23102501          else {
    2311             if (i < MAXARG_sBx && i > -MAXARG_sBx) {
    2312               co = MKOP_AsBx(OP_LOADI, cursp(), i);
     2502#endif
     2503            if (i == -1) genop_1(s, OP_LOADI__1, cursp());
     2504            else if (i >= -0xffff) {
     2505              genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
    23132506            }
    23142507            else {
    23152508              int off = new_lit(s, mrb_fixnum_value(i));
    2316               co = MKOP_ABx(OP_LOADL, cursp(), off);
     2509              genop_2(s, OP_LOADL, cursp(), off);
    23172510            }
    2318             genop(s, co);
    2319           }
     2511#ifndef MRB_WITHOUT_FLOAT
     2512          }
     2513#endif
    23202514          push();
    23212515        }
     
    23242518      default:
    23252519        if (val) {
    2326           int sym = new_msym(s, mrb_intern_lit(s->mrb, "-"));
    2327 
    2328           genop(s, MKOP_ABx(OP_LOADI, cursp(), 0));
     2520          int sym = new_sym(s, mrb_intern_lit(s->mrb, "-@"));
     2521          codegen(s, tree, VAL);
     2522          pop();
     2523          genop_3(s, OP_SEND, cursp(), sym, 0);
    23292524          push();
    2330           codegen(s, tree, VAL);
    2331           pop(); pop();
    2332           genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2));
    23332525        }
    23342526        else {
     
    23482540
    23492541      mrb_gc_arena_restore(s->mrb, ai);
    2350       genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2542      genop_2(s, OP_STRING, cursp(), off);
    23512543      push();
    23522544    }
     
    23612553
    23622554      if (!n) {
    2363         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2555        genop_1(s, OP_LOADNIL, cursp());
    23642556        push();
    23652557        break;
     
    23702562        codegen(s, n->car, VAL);
    23712563        pop(); pop();
    2372         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     2564        genop_1(s, OP_STRCAT, cursp());
    23732565        push();
    23742566        n = n->cdr;
     
    23792571
    23802572      while (n) {
    2381         if ((intptr_t)n->car->car != NODE_STR) {
     2573        if (nint(n->car->car) != NODE_STR) {
    23822574          codegen(s, n->car, NOVAL);
    23832575        }
     
    24012593      int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel"));
    24022594
    2403       genop(s, MKOP_A(OP_LOADSELF, cursp()));
     2595      genop_1(s, OP_LOADSELF, cursp());
    24042596      push();
    24052597      codegen(s, tree->car, VAL);
    24062598      n = tree->cdr;
    24072599      while (n) {
    2408         if ((intptr_t)n->car->car == NODE_XSTR) {
     2600        if (nint(n->car->car) == NODE_XSTR) {
    24092601          n->car->car = (struct mrb_ast_node*)(intptr_t)NODE_STR;
    24102602          mrb_assert(!n->cdr); /* must be the end */
     
    24122604        codegen(s, n->car, VAL);
    24132605        pop(); pop();
    2414         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     2606        genop_1(s, OP_STRCAT, cursp());
    24152607        push();
    24162608        n = n->cdr;
     
    24192611      pop_n(3);
    24202612      sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
    2421       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
     2613      genop_3(s, OP_SEND, cursp(), sym, 1);
    24222614      if (val) push();
    24232615      mrb_gc_arena_restore(s->mrb, ai);
     
    24332625      int sym;
    24342626
    2435       genop(s, MKOP_A(OP_LOADSELF, cursp()));
     2627      genop_1(s, OP_LOADSELF, cursp());
    24362628      push();
    2437       genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2629      genop_2(s, OP_STRING, cursp(), off);
    24382630      push(); push();
    24392631      pop_n(3);
    24402632      sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
    2441       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
     2633      genop_3(s, OP_SEND, cursp(), sym, 1);
    24422634      if (val) push();
    24432635      mrb_gc_arena_restore(s->mrb, ai);
     
    24552647      int argc = 1;
    24562648
    2457       genop(s, MKOP_A(OP_OCLASS, cursp()));
    2458       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     2649      genop_1(s, OP_OCLASS, cursp());
     2650      genop_2(s, OP_GETMCNST, cursp(), sym);
    24592651      push();
    2460       genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2652      genop_2(s, OP_STRING, cursp(), off);
     2653      push();
    24612654      if (p2 || p3) {
     2655        if (p2) { /* opt */
     2656          off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
     2657          genop_2(s, OP_STRING, cursp(), off);
     2658        }
     2659        else {
     2660          genop_1(s, OP_LOADNIL, cursp());
     2661        }
    24622662        push();
    2463         if (p2) {
    2464           off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
    2465           genop(s, MKOP_ABx(OP_STRING, cursp(), off));
    2466         }
    2467         else {
    2468           genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2469         }
    24702663        argc++;
    2471         if (p3) {
     2664        if (p3) { /* enc */
     2665          off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
     2666          genop_2(s, OP_STRING, cursp(), off);
    24722667          push();
    2473           off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
    2474           genop(s, MKOP_ABx(OP_STRING, cursp(), off));
    24752668          argc++;
    2476           pop();
    2477         }
    2478         pop();
    2479       }
    2480       pop();
     2669        }
     2670      }
     2671      push(); /* space for a block */
     2672      pop_n(argc+2);
    24812673      sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
    2482       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
     2674      genop_3(s, OP_SEND, cursp(), sym, argc);
    24832675      mrb_gc_arena_restore(s->mrb, ai);
    24842676      push();
     
    24952687      char *p;
    24962688
    2497       genop(s, MKOP_A(OP_OCLASS, cursp()));
    2498       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     2689      genop_1(s, OP_OCLASS, cursp());
     2690      genop_2(s, OP_GETMCNST, cursp(), sym);
    24992691      push();
    25002692      codegen(s, n->car, VAL);
     
    25032695        codegen(s, n->car, VAL);
    25042696        pop(); pop();
    2505         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     2697        genop_1(s, OP_STRCAT, cursp());
    25062698        push();
    25072699        n = n->cdr;
    25082700      }
    25092701      n = tree->cdr->cdr;
    2510       if (n->car) {
     2702      if (n->car) { /* tail */
    25112703        p = (char*)n->car;
    25122704        off = new_lit(s, mrb_str_new_cstr(s->mrb, p));
    25132705        codegen(s, tree->car, VAL);
    2514         genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2706        genop_2(s, OP_STRING, cursp(), off);
    25152707        pop();
    2516         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
    2517       }
    2518       if (n->cdr->car) {
     2708        genop_1(s, OP_STRCAT, cursp());
     2709        push();
     2710      }
     2711      if (n->cdr->car) { /* opt */
    25192712        char *p2 = (char*)n->cdr->car;
    2520 
     2713        off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
     2714        genop_2(s, OP_STRING, cursp(), off);
    25212715        push();
     2716        argc++;
     2717      }
     2718      if (n->cdr->cdr) { /* enc */
     2719        char *p2 = (char*)n->cdr->cdr;
    25222720        off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
    2523         genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2721        genop_2(s, OP_STRING, cursp(), off);
     2722        push();
    25242723        argc++;
    25252724      }
    2526       if (n->cdr->cdr) {
    2527         char *p2 = (char*)n->cdr->cdr;
    2528 
    2529         push();
    2530         off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
    2531         genop(s, MKOP_ABx(OP_STRING, cursp(), off));
    2532         argc++;
    2533       }
    2534       pop_n(argc);
     2725      push(); /* space for a block */
     2726      pop_n(argc+2);
    25352727      sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
    2536       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
     2728      genop_3(s, OP_SEND, cursp(), sym, argc);
    25372729      mrb_gc_arena_restore(s->mrb, ai);
    25382730      push();
     
    25422734
    25432735      while (n) {
    2544         if ((intptr_t)n->car->car != NODE_STR) {
     2736        if (nint(n->car->car) != NODE_STR) {
    25452737          codegen(s, n->car, NOVAL);
    25462738        }
     
    25522744  case NODE_SYM:
    25532745    if (val) {
    2554       int sym = new_sym(s, sym(tree));
    2555 
    2556       genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
     2746      int sym = new_sym(s, nsym(tree));
     2747
     2748      genop_2(s, OP_LOADSYM, cursp(), sym);
    25572749      push();
    25582750    }
     
    25622754    codegen(s, tree, val);
    25632755    if (val) {
    2564       gen_send_intern(s);
     2756      gen_intern(s);
    25652757    }
    25662758    break;
     
    25682760  case NODE_SELF:
    25692761    if (val) {
    2570       genop(s, MKOP_A(OP_LOADSELF, cursp()));
     2762      genop_1(s, OP_LOADSELF, cursp());
    25712763      push();
    25722764    }
     
    25752767  case NODE_NIL:
    25762768    if (val) {
    2577       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2769      genop_1(s, OP_LOADNIL, cursp());
    25782770      push();
    25792771    }
     
    25822774  case NODE_TRUE:
    25832775    if (val) {
    2584       genop(s, MKOP_A(OP_LOADT, cursp()));
     2776      genop_1(s, OP_LOADT, cursp());
    25852777      push();
    25862778    }
     
    25892781  case NODE_FALSE:
    25902782    if (val) {
    2591       genop(s, MKOP_A(OP_LOADF, cursp()));
     2783      genop_1(s, OP_LOADF, cursp());
    25922784      push();
    25932785    }
     
    25962788  case NODE_ALIAS:
    25972789    {
    2598       int a = new_msym(s, sym(tree->car));
    2599       int b = new_msym(s, sym(tree->cdr));
    2600       int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method"));
    2601 
    2602       genop(s, MKOP_A(OP_TCLASS, cursp()));
    2603       push();
    2604       genop(s, MKOP_ABx(OP_LOADSYM, cursp(), a));
    2605       push();
    2606       genop(s, MKOP_ABx(OP_LOADSYM, cursp(), b));
    2607       push();
    2608       genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2609       push();
    2610       pop_n(4);
    2611       genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2));
     2790      int a = new_sym(s, nsym(tree->car));
     2791      int b = new_sym(s, nsym(tree->cdr));
     2792
     2793      genop_2(s, OP_ALIAS, a, b);
    26122794      if (val) {
     2795        genop_1(s, OP_LOADNIL, cursp());
    26132796        push();
    26142797      }
     
    26182801  case NODE_UNDEF:
    26192802    {
    2620       int undef = new_msym(s, mrb_intern_lit(s->mrb, "undef_method"));
    2621       int num = 0;
    26222803      node *t = tree;
    26232804
    2624       genop(s, MKOP_A(OP_TCLASS, cursp()));
    2625       push();
    26262805      while (t) {
    2627         int symbol;
    2628         if (num >= CALL_MAXARGS - 1) {
    2629           pop_n(num);
    2630           genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num));
    2631           while (t) {
    2632             symbol = new_msym(s, sym(t->car));
    2633             push();
    2634             genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
    2635             pop();
    2636             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
    2637             t = t->cdr;
    2638           }
    2639           num = CALL_MAXARGS;
    2640           break;
    2641         }
    2642         symbol = new_msym(s, sym(t->car));
    2643         genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
    2644         push();
     2806        int symbol = new_sym(s, nsym(t->car));
     2807        genop_1(s, OP_UNDEF, symbol);
    26452808        t = t->cdr;
    2646         num++;
    2647       }
    2648       pop();
    2649       if (num < CALL_MAXARGS) {
    2650         pop_n(num);
    2651       }
    2652       genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num));
     2809      }
    26532810      if (val) {
     2811        genop_1(s, OP_LOADNIL, cursp());
    26542812        push();
    26552813      }
     
    26602818    {
    26612819      int idx;
     2820      node *body;
    26622821
    26632822      if (tree->car->car == (node*)0) {
    2664         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2823        genop_1(s, OP_LOADNIL, cursp());
    26652824        push();
    26662825      }
    26672826      else if (tree->car->car == (node*)1) {
    2668         genop(s, MKOP_A(OP_OCLASS, cursp()));
     2827        genop_1(s, OP_OCLASS, cursp());
    26692828        push();
    26702829      }
     
    26762835      }
    26772836      else {
    2678         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2837        genop_1(s, OP_LOADNIL, cursp());
    26792838        push();
    26802839      }
    26812840      pop(); pop();
    2682       idx = new_msym(s, sym(tree->car->cdr));
    2683       genop(s, MKOP_AB(OP_CLASS, cursp(), idx));
    2684       idx = scope_body(s, tree->cdr->cdr->car, val);
    2685       genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
     2841      idx = new_sym(s, nsym(tree->car->cdr));
     2842      genop_2(s, OP_CLASS, cursp(), idx);
     2843      body = tree->cdr->cdr->car;
     2844      if (nint(body->cdr->car) == NODE_BEGIN && body->cdr->cdr == NULL) {
     2845        genop_1(s, OP_LOADNIL, cursp());
     2846      }
     2847      else {
     2848        idx = scope_body(s, body, val);
     2849        genop_2(s, OP_EXEC, cursp(), idx);
     2850      }
    26862851      if (val) {
    26872852        push();
     
    26952860
    26962861      if (tree->car->car == (node*)0) {
    2697         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2862        genop_1(s, OP_LOADNIL, cursp());
    26982863        push();
    26992864      }
    27002865      else if (tree->car->car == (node*)1) {
    2701         genop(s, MKOP_A(OP_OCLASS, cursp()));
     2866        genop_1(s, OP_OCLASS, cursp());
    27022867        push();
    27032868      }
     
    27062871      }
    27072872      pop();
    2708       idx = new_msym(s, sym(tree->car->cdr));
    2709       genop(s, MKOP_AB(OP_MODULE, cursp(), idx));
    2710       idx = scope_body(s, tree->cdr->car, val);
    2711       genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
     2873      idx = new_sym(s, nsym(tree->car->cdr));
     2874      genop_2(s, OP_MODULE, cursp(), idx);
     2875      if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN &&
     2876          tree->cdr->car->cdr->cdr == NULL) {
     2877        genop_1(s, OP_LOADNIL, cursp());
     2878      }
     2879      else {
     2880        idx = scope_body(s, tree->cdr->car, val);
     2881        genop_2(s, OP_EXEC, cursp(), idx);
     2882      }
    27122883      if (val) {
    27132884        push();
     
    27222893      codegen(s, tree->car, VAL);
    27232894      pop();
    2724       genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
    2725       idx = scope_body(s, tree->cdr->car, val);
    2726       genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
     2895      genop_1(s, OP_SCLASS, cursp());
     2896      if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN &&
     2897          tree->cdr->car->cdr->cdr == NULL) {
     2898        genop_1(s, OP_LOADNIL, cursp());
     2899      }
     2900      else {
     2901        idx = scope_body(s, tree->cdr->car, val);
     2902        genop_2(s, OP_EXEC, cursp(), idx);
     2903      }
    27272904      if (val) {
    27282905        push();
     
    27332910  case NODE_DEF:
    27342911    {
    2735       int sym = new_msym(s, sym(tree->car));
     2912      int sym = new_sym(s, nsym(tree->car));
    27362913      int idx = lambda_body(s, tree->cdr, 0);
    27372914
    2738       genop(s, MKOP_A(OP_TCLASS, cursp()));
     2915      genop_1(s, OP_TCLASS, cursp());
    27392916      push();
    2740       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
     2917      genop_2(s, OP_METHOD, cursp(), idx);
    27412918      push(); pop();
    27422919      pop();
    2743       genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
     2920      genop_2(s, OP_DEF, cursp(), sym);
    27442921      if (val) {
    2745         genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
     2922        genop_2(s, OP_LOADSYM, cursp(), sym);
    27462923        push();
    27472924      }
     
    27522929    {
    27532930      node *recv = tree->car;
    2754       int sym = new_msym(s, sym(tree->cdr->car));
     2931      int sym = new_sym(s, nsym(tree->cdr->car));
    27552932      int idx = lambda_body(s, tree->cdr->cdr, 0);
    27562933
    27572934      codegen(s, recv, VAL);
    27582935      pop();
    2759       genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
     2936      genop_1(s, OP_SCLASS, cursp());
    27602937      push();
    2761       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
     2938      genop_2(s, OP_METHOD, cursp(), idx);
    27622939      pop();
    2763       genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
     2940      genop_2(s, OP_DEF, cursp(), sym);
    27642941      if (val) {
    2765         genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
     2942        genop_2(s, OP_LOADSYM, cursp(), sym);
    27662943        push();
    27672944      }
     
    28022979  codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
    28032980
    2804   if (!p) return NULL;
     2981  if (!p) {
     2982    if (prev)
     2983      codegen_error(prev, "unexpected scope");
     2984    return NULL;
     2985  }
    28052986  *p = codegen_scope_zero;
    28062987  p->mrb = mrb;
     
    28253006  p->irep->plen = 0;
    28263007
    2827   p->scapa = MAXMSYMLEN;
     3008  p->scapa = 256;
    28283009  p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa);
    28293010  p->irep->slen = 0;
     
    28503031  p->ai = mrb_gc_arena_save(mrb);
    28513032
    2852   p->filename = prev->filename;
    2853   if (p->filename) {
     3033  p->filename_sym = prev->filename_sym;
     3034  if (p->filename_sym) {
    28543035    p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa);
    28553036  }
     
    28583039  /* debug setting */
    28593040  p->debug_start_pos = 0;
    2860   if (p->filename) {
     3041  if (p->filename_sym) {
    28613042    mrb_debug_info_alloc(mrb, p->irep);
    2862     p->irep->filename = p->filename;
    2863     p->irep->lines = p->lines;
    28643043  }
    28653044  else {
     
    28793058  mrb_state *mrb = s->mrb;
    28803059  mrb_irep *irep = s->irep;
    2881   size_t fname_len;
    2882   char *fname;
    2883 
     3060
     3061  if (s->nlocals >= 0x3ff) {
     3062    codegen_error(s, "too many local variables");
     3063  }
    28843064  irep->flags = 0;
    28853065  if (s->iseq) {
    28863066    irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
    28873067    irep->ilen = s->pc;
    2888     if (s->lines) {
    2889       irep->lines = (uint16_t *)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->pc);
    2890     }
    2891     else {
    2892       irep->lines = 0;
    2893     }
    28943068  }
    28953069  irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen);
    28963070  irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen);
    28973071  irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
    2898   if (s->filename) {
    2899     irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);
    2900     mrb_debug_info_append_file(mrb, irep, s->debug_start_pos, s->pc);
    2901 
    2902     fname_len = strlen(s->filename);
    2903     fname = (char*)codegen_malloc(s, fname_len + 1);
    2904     memcpy(fname, s->filename, fname_len);
    2905     fname[fname_len] = '\0';
    2906     irep->filename = fname;
    2907     irep->own_filename = TRUE;
    2908   }
     3072  if (s->filename_sym) {
     3073    mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
     3074    const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
     3075
     3076    mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
     3077                               filename, s->lines, s->debug_start_pos, s->pc);
     3078  }
     3079  mrb_free(s->mrb, s->lines);
    29093080
    29103081  irep->nlocals = s->nlocals;
     
    29213092
    29223093  p->type = t;
    2923   p->pc1 = p->pc2 = p->pc3 = 0;
     3094  p->pc0 = p->pc1 = p->pc2 = p->pc3 = 0;
    29243095  p->prev = s->loop;
    29253096  p->ensure_level = s->ensure_level;
     
    29393110  else {
    29403111    struct loopinfo *loop;
     3112    int n = 0;
    29413113
    29423114    if (tree) {
     
    29453117
    29463118    loop = s->loop;
    2947     while (loop && loop->type == LOOP_BEGIN) {
    2948       genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
    2949       loop = loop->prev;
    2950     }
    2951     while (loop && loop->type == LOOP_RESCUE) {
    2952       loop = loop->prev;
     3119    while (loop) {
     3120      if (loop->type == LOOP_BEGIN) {
     3121        n++;
     3122        loop = loop->prev;
     3123      }
     3124      else if (loop->type == LOOP_RESCUE) {
     3125        loop = loop->prev;
     3126      }
     3127      else{
     3128        break;
     3129      }
    29533130    }
    29543131    if (!loop) {
     
    29563133      return;
    29573134    }
     3135    if (n > 0) {
     3136      genop_1(s, OP_POPERR, n);
     3137    }
    29583138
    29593139    if (loop->type == LOOP_NORMAL) {
     
    29613141
    29623142      if (s->ensure_level > s->loop->ensure_level) {
    2963         genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
     3143        genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
    29643144      }
    29653145      if (tree) {
    2966         genop_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);
    2967       }
    2968       tmp = genop(s, MKOP_sBx(OP_JMP, loop->pc3));
     3146        gen_move(s, loop->acc, cursp(), 0);
     3147      }
     3148      tmp = genjmp(s, OP_JMP, loop->pc3);
    29693149      loop->pc3 = tmp;
    29703150    }
    29713151    else {
    29723152      if (!tree) {
    2973         genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2974       }
    2975       genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK));
     3153        genop_1(s, OP_LOADNIL, cursp());
     3154      }
     3155      gen_return(s, OP_BREAK, cursp());
    29763156    }
    29773157  }
     
    29813161loop_pop(codegen_scope *s, int val)
    29823162{
     3163  if (val) {
     3164    genop_1(s, OP_LOADNIL, cursp());
     3165  }
    29833166  dispatch_linked(s, s->loop->pc3);
    2984   if (val) {
    2985     genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2986   }
    29873167  s->loop = s->loop->prev;
    29883168  if (val) push();
    29893169}
    29903170
    2991 MRB_API struct RProc*
    2992 mrb_generate_code(mrb_state *mrb, parser_state *p)
     3171static struct RProc*
     3172generate_code(mrb_state *mrb, parser_state *p, int val)
    29933173{
    29943174  codegen_scope *scope = scope_new(mrb, 0, 0);
     
    29963176  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
    29973177
    2998   if (!scope) {
    2999     return NULL;
    3000   }
    30013178  scope->mrb = mrb;
    30023179  scope->parser = p;
    3003   scope->filename = p->filename;
     3180  scope->filename_sym = p->filename_sym;
    30043181  scope->filename_index = p->current_filename_index;
    30053182
    30063183  MRB_TRY(&scope->jmp) {
    3007     mrb->jmp = &scope->jmp; 
     3184    mrb->jmp = &scope->jmp;
    30083185    /* prepare irep */
    3009     codegen(scope, p->tree, NOVAL);
     3186    codegen(scope, p->tree, val);
    30103187    proc = mrb_proc_new(mrb, scope->irep);
    30113188    mrb_irep_decref(mrb, scope->irep);
    30123189    mrb_pool_close(scope->mpool);
    30133190    proc->c = NULL;
     3191    if (mrb->c->cibase && mrb->c->cibase->proc == proc->upper) {
     3192      proc->upper = NULL;
     3193    }
    30143194    mrb->jmp = prev_jmp;
    30153195    return proc;
     
    30233203  MRB_END_EXC(&scope->jmp);
    30243204}
     3205
     3206MRB_API struct RProc*
     3207mrb_generate_code(mrb_state *mrb, parser_state *p)
     3208{
     3209  return generate_code(mrb, p, VAL);
     3210}
     3211
     3212void
     3213mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep)
     3214{
     3215  int i;
     3216
     3217  if (irep->lv) {
     3218    mrb_free(mrb, irep->lv);
     3219    irep->lv = NULL;
     3220  }
     3221
     3222  for (i = 0; i < irep->rlen; ++i) {
     3223    mrb_irep_remove_lv(mrb, irep->reps[i]);
     3224  }
     3225}
     3226
     3227#undef OPCODE
     3228#define Z 1
     3229#define S 3
     3230#define W 4
     3231/* instruction sizes */
     3232uint8_t mrb_insn_size[] = {
     3233#define B 2
     3234#define BB 3
     3235#define BBB 4
     3236#define BS 4
     3237#define SB 4
     3238#define OPCODE(_,x) x,
     3239#include "mruby/ops.h"
     3240#undef OPCODE
     3241#undef B
     3242#undef BB
     3243#undef BS
     3244#undef SB
     3245#undef BBB
     3246};
     3247/* EXT1 instruction sizes */
     3248uint8_t mrb_insn_size1[] = {
     3249#define B 3
     3250#define BB 4
     3251#define BBB 5
     3252#define BS 5
     3253#define SB 5
     3254#define OPCODE(_,x) x,
     3255#include "mruby/ops.h"
     3256#undef OPCODE
     3257#undef B
     3258};
     3259/* EXT2 instruction sizes */
     3260uint8_t mrb_insn_size2[] = {
     3261#define B 2
     3262#define OPCODE(_,x) x,
     3263#include "mruby/ops.h"
     3264#undef OPCODE
     3265#undef BB
     3266#undef BBB
     3267#undef BS
     3268#undef SB
     3269};
     3270/* EXT3 instruction sizes */
     3271#define BB 5
     3272#define BBB 6
     3273#define BS 4
     3274#define SB 5
     3275uint8_t mrb_insn_size3[] = {
     3276#define OPCODE(_,x) x,
     3277#include "mruby/ops.h"
     3278};
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/keywords

    r270 r439  
    11%{
    22struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
    3 const struct kwtable *mrb_reserved_word(const char *, unsigned int);
    4 static const struct kwtable *reserved_word(const char *, unsigned int);
    5 #define mrb_reserved_word(str, len) reserved_word(str, len)
    63%}
    74
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/lex.def

    r331 r439  
    1 /* ANSI-C code produced by gperf version 3.0.4 */
     1/* ANSI-C code produced by gperf version 3.1 */
    22/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords  */
    33
     
    2626      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
    2727/* The character set is not based on ISO-646.  */
    28 #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
     28#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
    2929#endif
    3030
     
    3232
    3333struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
    34 const struct kwtable *mrb_reserved_word(const char *, unsigned int);
    35 static const struct kwtable *reserved_word(const char *, unsigned int);
    36 #define mrb_reserved_word(str, len) reserved_word(str, len)
    37 #line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     34#line 5 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    3835struct kwtable;
    3936
     
    5350#endif
    5451static unsigned int
    55 hash (register const char *str, register unsigned int len)
     52hash (register const char *str, register size_t len)
    5653{
    5754  static const unsigned char asso_values[] =
     
    8481      51, 51, 51, 51, 51, 51
    8582    };
    86   register int hval = len;
     83  register unsigned int hval = len;
    8784
    8885  switch (hval)
     
    9996}
    10097
    101 #ifdef __GNUC__
    102 __inline
    103 #if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
    104 __attribute__ ((__gnu_inline__))
    105 #endif
    106 #endif
    10798const struct kwtable *
    108 mrb_reserved_word (register const char *str, register unsigned int len)
     99mrb_reserved_word (register const char *str, register size_t len)
    109100{
    110101  static const struct kwtable wordlist[] =
    111102    {
    112103      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
     104#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     105      {"break",        {keyword_break,       keyword_break},       EXPR_MID},
     106#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     107      {"else",         {keyword_else,        keyword_else},        EXPR_BEG},
     108#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     109      {"nil",          {keyword_nil,         keyword_nil},         EXPR_END},
     110#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     111      {"ensure",       {keyword_ensure,      keyword_ensure},      EXPR_BEG},
     112#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     113      {"end",          {keyword_end,         keyword_end},         EXPR_END},
     114#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     115      {"then",         {keyword_then,        keyword_then},        EXPR_BEG},
     116#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     117      {"not",          {keyword_not,         keyword_not},         EXPR_ARG},
     118#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     119      {"false",        {keyword_false,       keyword_false},       EXPR_END},
     120#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     121      {"self",         {keyword_self,        keyword_self},        EXPR_END},
     122#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     123      {"elsif",        {keyword_elsif,       keyword_elsif},       EXPR_VALUE},
     124#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     125      {"rescue",       {keyword_rescue,      modifier_rescue},     EXPR_MID},
     126#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     127      {"true",         {keyword_true,        keyword_true},        EXPR_END},
     128#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     129      {"until",        {keyword_until,       modifier_until},      EXPR_VALUE},
     130#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     131      {"unless",       {keyword_unless,      modifier_unless},     EXPR_VALUE},
     132#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     133      {"return",       {keyword_return,      keyword_return},      EXPR_MID},
    113134#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    114       {"break",        {keyword_break,       keyword_break},       EXPR_MID},
    115 #line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    116       {"else",         {keyword_else,        keyword_else},        EXPR_BEG},
     135      {"def",          {keyword_def,         keyword_def},         EXPR_FNAME},
     136#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     137      {"and",          {keyword_and,         keyword_and},         EXPR_VALUE},
     138#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     139      {"do",           {keyword_do,          keyword_do},          EXPR_BEG},
     140#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     141      {"yield",        {keyword_yield,       keyword_yield},       EXPR_ARG},
     142#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     143      {"for",          {keyword_for,         keyword_for},         EXPR_VALUE},
     144#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     145      {"undef",        {keyword_undef,       keyword_undef},       EXPR_FNAME},
     146#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     147      {"or",           {keyword_or,          keyword_or},          EXPR_VALUE},
     148#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     149      {"in",           {keyword_in,          keyword_in},          EXPR_VALUE},
     150#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     151      {"when",         {keyword_when,        keyword_when},        EXPR_VALUE},
     152#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     153      {"retry",        {keyword_retry,       keyword_retry},       EXPR_END},
     154#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     155      {"if",           {keyword_if,          modifier_if},         EXPR_VALUE},
     156#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     157      {"case",         {keyword_case,        keyword_case},        EXPR_VALUE},
    117158#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    118       {"nil",          {keyword_nil,         keyword_nil},         EXPR_END},
    119 #line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    120       {"ensure",       {keyword_ensure,      keyword_ensure},      EXPR_BEG},
    121 #line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    122       {"end",          {keyword_end,         keyword_end},         EXPR_END},
    123 #line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    124       {"then",         {keyword_then,        keyword_then},        EXPR_BEG},
    125 #line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    126       {"not",          {keyword_not,         keyword_not},         EXPR_ARG},
    127 #line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    128       {"false",        {keyword_false,       keyword_false},       EXPR_END},
    129 #line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    130       {"self",         {keyword_self,        keyword_self},        EXPR_END},
    131 #line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    132       {"elsif",        {keyword_elsif,       keyword_elsif},       EXPR_VALUE},
    133 #line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    134       {"rescue",       {keyword_rescue,      modifier_rescue},     EXPR_MID},
    135 #line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    136       {"true",         {keyword_true,        keyword_true},        EXPR_END},
    137 #line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    138       {"until",        {keyword_until,       modifier_until},      EXPR_VALUE},
    139 #line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    140       {"unless",       {keyword_unless,      modifier_unless},     EXPR_VALUE},
    141 #line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    142       {"return",       {keyword_return,      keyword_return},      EXPR_MID},
    143 #line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    144       {"def",          {keyword_def,         keyword_def},         EXPR_FNAME},
    145 #line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    146       {"and",          {keyword_and,         keyword_and},         EXPR_VALUE},
    147 #line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    148       {"do",           {keyword_do,          keyword_do},          EXPR_BEG},
    149 #line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    150       {"yield",        {keyword_yield,       keyword_yield},       EXPR_ARG},
     159      {"redo",         {keyword_redo,        keyword_redo},        EXPR_END},
     160#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     161      {"next",         {keyword_next,        keyword_next},        EXPR_MID},
     162#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     163      {"super",        {keyword_super,       keyword_super},       EXPR_ARG},
    151164#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    152       {"for",          {keyword_for,         keyword_for},         EXPR_VALUE},
    153 #line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    154       {"undef",        {keyword_undef,       keyword_undef},       EXPR_FNAME},
    155 #line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    156       {"or",           {keyword_or,          keyword_or},          EXPR_VALUE},
    157 #line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    158       {"in",           {keyword_in,          keyword_in},          EXPR_VALUE},
    159 #line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    160       {"when",         {keyword_when,        keyword_when},        EXPR_VALUE},
    161 #line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    162       {"retry",        {keyword_retry,       keyword_retry},       EXPR_END},
    163 #line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    164       {"if",           {keyword_if,          modifier_if},         EXPR_VALUE},
    165 #line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    166       {"case",         {keyword_case,        keyword_case},        EXPR_VALUE},
    167 #line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    168       {"redo",         {keyword_redo,        keyword_redo},        EXPR_END},
    169 #line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    170       {"next",         {keyword_next,        keyword_next},        EXPR_MID},
    171 #line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    172       {"super",        {keyword_super,       keyword_super},       EXPR_ARG},
    173 #line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    174165      {"module",       {keyword_module,      keyword_module},      EXPR_VALUE},
    175 #line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     166#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    176167      {"begin",        {keyword_begin,       keyword_begin},       EXPR_BEG},
     168#line 9 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     169      {"__LINE__",     {keyword__LINE__,     keyword__LINE__},     EXPR_END},
     170#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     171      {"__FILE__",     {keyword__FILE__,     keyword__FILE__},     EXPR_END},
     172#line 7 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     173      {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
     174#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     175      {"END",          {keyword_END,         keyword_END},         EXPR_END},
    177176#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    178       {"__LINE__",     {keyword__LINE__,     keyword__LINE__},     EXPR_END},
    179 #line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    180       {"__FILE__",     {keyword__FILE__,     keyword__FILE__},     EXPR_END},
     177      {"alias",        {keyword_alias,       keyword_alias},       EXPR_FNAME},
    181178#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    182       {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
    183 #line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    184       {"END",          {keyword_END,         keyword_END},         EXPR_END},
    185 #line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    186       {"alias",        {keyword_alias,       keyword_alias},       EXPR_FNAME},
    187 #line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    188179      {"BEGIN",        {keyword_BEGIN,       keyword_BEGIN},       EXPR_END},
    189180      {""},
    190 #line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     181#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    191182      {"class",        {keyword_class,       keyword_class},       EXPR_CLASS},
    192183      {""}, {""},
    193 #line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     184#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    194185      {"while",        {keyword_while,       modifier_while},      EXPR_VALUE}
    195186    };
     
    197188  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
    198189    {
    199       register int key = hash (str, len);
    200 
    201       if (key <= MAX_HASH_VALUE && key >= 0)
     190      register unsigned int key = hash (str, len);
     191
     192      if (key <= MAX_HASH_VALUE)
    202193        {
    203194          register const char *s = wordlist[key].name;
     
    209200  return 0;
    210201}
    211 #line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
    212 
     202#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
     203
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/node.h

    r331 r439  
    1010enum node_type {
    1111  NODE_METHOD,
    12   NODE_FBODY,
    13   NODE_CFUNC,
    1412  NODE_SCOPE,
    1513  NODE_BLOCK,
     
    1715  NODE_CASE,
    1816  NODE_WHEN,
    19   NODE_OPT_N,
    2017  NODE_WHILE,
    2118  NODE_UNTIL,
     
    4138  NODE_SCALL,
    4239  NODE_FCALL,
    43   NODE_VCALL,
    4440  NODE_SUPER,
    4541  NODE_ZSUPER,
     
    4743  NODE_ZARRAY,
    4844  NODE_HASH,
     45  NODE_KW_HASH,
    4946  NODE_RETURN,
    5047  NODE_YIELD,
     
    5552  NODE_CONST,
    5653  NODE_CVAR,
     54  NODE_NVAR,
    5755  NODE_NTH_REF,
    5856  NODE_BACK_REF,
    5957  NODE_MATCH,
    60   NODE_MATCH2,
    61   NODE_MATCH3,
    6258  NODE_INT,
    6359  NODE_FLOAT,
     
    7268  NODE_DREGX,
    7369  NODE_DREGX_ONCE,
    74   NODE_LIST,
    7570  NODE_ARG,
    76   NODE_ARGSCAT,
    77   NODE_ARGSPUSH,
     71  NODE_ARGS_TAIL,
     72  NODE_KW_ARG,
     73  NODE_KW_REST_ARGS,
    7874  NODE_SPLAT,
    7975  NODE_TO_ARY,
     
    8985  NODE_COLON2,
    9086  NODE_COLON3,
    91   NODE_CREF,
    9287  NODE_DOT2,
    9388  NODE_DOT3,
    94   NODE_FLIP2,
    95   NODE_FLIP3,
    96   NODE_ATTRSET,
    9789  NODE_SELF,
    9890  NODE_NIL,
     
    10092  NODE_FALSE,
    10193  NODE_DEFINED,
    102   NODE_NEWLINE,
    10394  NODE_POSTEXE,
    104   NODE_ALLOCA,
    105   NODE_DMETHOD,
    106   NODE_BMETHOD,
    107   NODE_MEMO,
    108   NODE_IFUNC,
    10995  NODE_DSYM,
    110   NODE_ATTRASGN,
    11196  NODE_HEREDOC,
    11297  NODE_LITERAL_DELIM,
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/parse.y

    r331 r439  
    1111#endif
    1212#define YYERROR_VERBOSE 1
    13 /*
    14  * Force yacc to use our memory management.  This is a little evil because
    15  * the macros assume that "parser_state *p" is in scope
    16  */
    17 #define YYMALLOC(n)    mrb_malloc(p->mrb, (n))
    18 #define YYFREE(o)      mrb_free(p->mrb, (o))
    19 #define YYSTACK_USE_ALLOCA 0
     13#define YYSTACK_USE_ALLOCA 1
    2014
    2115#include <ctype.h>
     
    2822#include <mruby/error.h>
    2923#include <mruby/throw.h>
     24#include <mruby/string.h>
    3025#include "node.h"
    3126
     
    7772#define intn(x) ((int)(intptr_t)(x))
    7873
     74#define NUM_SUFFIX_R   (1<<0)
     75#define NUM_SUFFIX_I   (1<<1)
     76
    7977static inline mrb_sym
    8078intern_cstr_gen(parser_state *p, const char *s)
     
    9189#define intern(s,len) intern_gen(p,(s),(len))
    9290
    93 static inline mrb_sym
    94 intern_gen_c(parser_state *p, const char c)
    95 {
    96   return mrb_intern(p->mrb, &c, 1);
    97 }
    98 #define intern_c(c) intern_gen_c(p,(c))
     91#define intern_lit(s) mrb_intern_lit(p->mrb, s)
    9992
    10093static void
     
    134127  c->lineno = p->lineno;
    135128  c->filename_index = p->current_filename_index;
     129  /* beginning of next partial file; need to point the previous file */
     130  if (p->lineno == 0 && p->current_filename_index > 0) {
     131    c->filename_index-- ;
     132  }
    136133  return c;
    137134}
     
    186183
    187184  if (!a) return b;
     185  if (!b) return a;
    188186  while (c->cdr) {
    189187    c = c->cdr;
    190188  }
    191   if (b) {
    192     c->cdr = b;
    193   }
     189  c->cdr = b;
    194190  return a;
    195191}
     
    216212#undef strdup
    217213#define strdup(s) parser_strdup(p, s)
     214
     215static void
     216dump_int(uint16_t i, char *s)
     217{
     218  char *p = s;
     219  char *t = s;
     220
     221  while (i > 0) {
     222    *p++ = (i % 10)+'0';
     223    i /= 10;
     224  }
     225  if (p == s) *p++ = '0';
     226  *p = 0;
     227  p--;  /* point the last char */
     228  while (t < p) {
     229    char c = *t;
     230    *t++ = *p;
     231    *p-- = c;
     232  }
     233}
    218234
    219235/* xxx ----------------------------- */
     
    280296}
    281297
     298static void
     299local_add_blk(parser_state *p, mrb_sym blk)
     300{
     301  /* allocate register for block */
     302  local_add_f(p, blk ? blk : mrb_intern_lit(p->mrb, "&"));
     303}
     304
     305static void
     306local_add_kw(parser_state *p, mrb_sym kwd)
     307{
     308  /* allocate register for keywords hash */
     309  local_add_f(p, kwd ? kwd : mrb_intern_lit(p->mrb, "**"));
     310}
     311
    282312static node*
    283313locals_node(parser_state *p)
    284314{
    285315  return p->locals ? p->locals->car : NULL;
     316}
     317
     318static void
     319nvars_nest(parser_state *p)
     320{
     321  p->nvars = cons(nint(0), p->nvars);
     322}
     323
     324static void
     325nvars_block(parser_state *p)
     326{
     327  p->nvars = cons(nint(-2), p->nvars);
     328}
     329
     330static void
     331nvars_unnest(parser_state *p)
     332{
     333  p->nvars = p->nvars->cdr;
    286334}
    287335
     
    569617}
    570618
     619/* (:kw_hash (k . v) (k . v)...) */
     620static node*
     621new_kw_hash(parser_state *p, node *a)
     622{
     623  return cons((node*)NODE_KW_HASH, a);
     624}
     625
    571626/* (:sym . a) */
    572627static node*
     
    613668}
    614669
     670/* (:nvar . a) */
     671static node*
     672new_nvar(parser_state *p, int num)
     673{
     674  int nvars = intn(p->nvars->car);
     675
     676  p->nvars->car = nint(nvars > num ? nvars : num);
     677  return cons((node*)NODE_NVAR, nint(num));
     678}
     679
    615680/* (:const . a) */
    616681static node*
     
    672737}
    673738
    674 /* (m o r m2 b) */
     739static void
     740local_add_margs(parser_state *p, node *n)
     741{
     742  while (n) {
     743    if (n->car->car == (node*)NODE_MASGN) {
     744      node *t = n->car->cdr->cdr;
     745
     746      n->car->cdr->cdr = NULL;
     747      while (t) {
     748        local_add_f(p, sym(t->car));
     749        t = t->cdr;
     750      }
     751      local_add_margs(p, n->car->cdr->car->car);
     752      local_add_margs(p, n->car->cdr->car->cdr->cdr->car);
     753    }
     754    n = n->cdr;
     755  }
     756}
     757
     758static void
     759local_add_lv(parser_state *p, node *lv)
     760{
     761  while (lv) {
     762    local_add_f(p, sym(lv->car));
     763    lv = lv->cdr;
     764  }
     765}
     766
     767/* (m o r m2 tail) */
    675768/* m: (a b c) */
    676769/* o: ((a . e1) (b . e2)) */
     
    679772/* b: a */
    680773static node*
    681 new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, mrb_sym blk)
     774new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail)
    682775{
    683776  node *n;
    684777
    685   n = cons(m2, nsym(blk));
     778  local_add_margs(p, m);
     779  local_add_margs(p, m2);
     780  n = cons(m2, tail);
    686781  n = cons(nsym(rest), n);
    687782  n = cons(opt, n);
     783  while (opt) {
     784    /* opt: (sym . (opt . lv)) -> (sym . opt) */
     785    local_add_lv(p, opt->car->cdr->cdr);
     786    opt->car->cdr = opt->car->cdr->car;
     787    opt = opt->cdr;
     788  }
    688789  return cons(m, n);
    689790}
    690791
     792/* (:args_tail keywords rest_keywords_sym block_sym) */
     793static node*
     794new_args_tail(parser_state *p, node *kws, node *kwrest, mrb_sym blk)
     795{
     796  node *k;
     797
     798  if (kws || kwrest) {
     799    local_add_kw(p, (kwrest && kwrest->cdr)? sym(kwrest->cdr) : 0);
     800  }
     801
     802  local_add_blk(p, blk);
     803
     804  /* allocate register for keywords arguments */
     805  /* order is for Proc#parameters */
     806  for (k = kws; k; k = k->cdr) {
     807    if (!k->car->cdr->cdr->car) { /* allocate required keywords */
     808      local_add_f(p, sym(k->car->cdr->car));
     809    }
     810  }
     811  for (k = kws; k; k = k->cdr) {
     812    if (k->car->cdr->cdr->car) { /* allocate keywords with default */
     813      local_add_lv(p, k->car->cdr->cdr->car->cdr);
     814      k->car->cdr->cdr->car = k->car->cdr->cdr->car->car;
     815      local_add_f(p, sym(k->car->cdr->car));
     816    }
     817  }
     818
     819  return list4((node*)NODE_ARGS_TAIL, kws, kwrest, nsym(blk));
     820}
     821
     822/* (:kw_arg kw_sym def_arg) */
     823static node*
     824new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg)
     825{
     826  mrb_assert(kw);
     827  return list3((node*)NODE_KW_ARG, nsym(kw), def_arg);
     828}
     829
    691830/* (:block_arg . a) */
    692831static node*
     
    696835}
    697836
     837static node*
     838setup_numparams(parser_state *p, node *a)
     839{
     840  int nvars = intn(p->nvars->car);
     841  if (nvars > 0) {
     842    int i;
     843    mrb_sym sym;
     844    // m || opt || rest || tail
     845    if (a && (a->car || (a->cdr && a->cdr->car) || (a->cdr->cdr && a->cdr->cdr->car) || (a->cdr->cdr->cdr->cdr && a->cdr->cdr->cdr->cdr->car))) {
     846      yyerror(p, "ordinary parameter is defined");
     847    }
     848    else if (p->locals) {
     849      /* p->locals should not be NULL unless error happens before the point */
     850      node* args = 0;
     851      for (i = nvars; i > 0; i--) {
     852        char buf[3];
     853
     854        buf[0] = '_';
     855        buf[1] = i+'0';
     856        buf[2] = '\0';
     857        sym = intern_cstr(buf);
     858        args = cons(new_arg(p, sym), args);
     859        p->locals->car = cons(nsym(sym), p->locals->car);
     860      }
     861      a = new_args(p, args, 0, 0, 0, 0);
     862    }
     863  }
     864  return a;
     865}
     866
    698867/* (:block arg body) */
    699868static node*
    700869new_block(parser_state *p, node *a, node *b)
    701870{
     871  a = setup_numparams(p, a);
    702872  return list4((node*)NODE_BLOCK, locals_node(p), a, b);
    703873}
     
    726896}
    727897
     898/* (:masgn mlhs mrhs) no check */
     899static node*
     900new_masgn_param(parser_state *p, node *a, node *b)
     901{
     902  return cons((node*)NODE_MASGN, cons(a, b));
     903}
     904
    728905/* (:asgn lhs rhs) */
    729906static node*
     
    734911}
    735912
     913static node*
     914new_imaginary(parser_state *p, node *imaginary)
     915{
     916  return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
     917}
     918
     919static node*
     920new_rational(parser_state *p, node *rational)
     921{
     922  return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Rational"), list1(list1(rational)), 1);
     923}
     924
    736925/* (:int . i) */
    737926static node*
    738 new_int(parser_state *p, const char *s, int base)
    739 {
    740   return list3((node*)NODE_INT, (node*)strdup(s), nint(base));
    741 }
    742 
     927new_int(parser_state *p, const char *s, int base, int suffix)
     928{
     929  node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base));
     930  if (suffix & NUM_SUFFIX_R) {
     931    result = new_rational(p, result);
     932  }
     933  if (suffix & NUM_SUFFIX_I) {
     934    result = new_imaginary(p, result);
     935  }
     936  return result;
     937}
     938
     939#ifndef MRB_WITHOUT_FLOAT
    743940/* (:float . i) */
    744941static node*
    745 new_float(parser_state *p, const char *s)
    746 {
    747   return cons((node*)NODE_FLOAT, (node*)strdup(s));
    748 }
     942new_float(parser_state *p, const char *s, int suffix)
     943{
     944  node* result = cons((node*)NODE_FLOAT, (node*)strdup(s));
     945  if (suffix & NUM_SUFFIX_R) {
     946    result = new_rational(p, result);
     947  }
     948  if (suffix & NUM_SUFFIX_I) {
     949    result = new_imaginary(p, result);
     950  }
     951  return result;
     952}
     953#endif
    749954
    750955/* (:str . (s . len)) */
    751956static node*
    752 new_str(parser_state *p, const char *s, int len)
     957new_str(parser_state *p, const char *s, size_t len)
    753958{
    754959  return cons((node*)NODE_STR, cons((node*)strndup(s, len), nint(len)));
     
    762967}
    763968
     969static int
     970string_node_p(node *n)
     971{
     972  return (int)((enum node_type)(intptr_t)n->car == NODE_STR);
     973}
     974
     975static node*
     976composite_string_node(parser_state *p, node *a, node *b)
     977{
     978  size_t newlen = (size_t)a->cdr + (size_t)b->cdr;
     979  char *str = (char*)mrb_pool_realloc(p->pool, a->car, (size_t)a->cdr + 1, newlen + 1);
     980  memcpy(str + (size_t)a->cdr, b->car, (size_t)b->cdr);
     981  str[newlen] = '\0';
     982  a->car = (node*)str;
     983  a->cdr = (node*)newlen;
     984  cons_free(b);
     985  return a;
     986}
     987
     988static node*
     989concat_string(parser_state *p, node *a, node *b)
     990{
     991  if (string_node_p(a)) {
     992    if (string_node_p(b)) {
     993      /* a == NODE_STR && b == NODE_STR */
     994      composite_string_node(p, a->cdr, b->cdr);
     995      cons_free(b);
     996      return a;
     997    }
     998    else {
     999      /* a == NODE_STR && b == NODE_DSTR */
     1000
     1001      if (string_node_p(b->cdr->car)) {
     1002        /* a == NODE_STR && b->[NODE_STR, ...] */
     1003        composite_string_node(p, a->cdr, b->cdr->car->cdr);
     1004        cons_free(b->cdr->car);
     1005        b->cdr->car = a;
     1006        return b;
     1007      }
     1008    }
     1009  }
     1010  else {
     1011    node *c; /* last node of a */
     1012    for (c = a; c->cdr != NULL; c = c->cdr) ;
     1013
     1014    if (string_node_p(b)) {
     1015      /* a == NODE_DSTR && b == NODE_STR */
     1016      if (string_node_p(c->car)) {
     1017        /* a->[..., NODE_STR] && b == NODE_STR */
     1018        composite_string_node(p, c->car->cdr, b->cdr);
     1019        cons_free(b);
     1020        return a;
     1021      }
     1022
     1023      push(a, b);
     1024      return a;
     1025    }
     1026    else {
     1027      /* a == NODE_DSTR && b == NODE_DSTR */
     1028      if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
     1029        /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
     1030        node *d = b->cdr;
     1031        cons_free(b);
     1032        composite_string_node(p, c->car->cdr, d->car->cdr);
     1033        cons_free(d->car);
     1034        c->cdr = d->cdr;
     1035        cons_free(d);
     1036        return a;
     1037      }
     1038      else {
     1039        c->cdr = b->cdr;
     1040        cons_free(b);
     1041        return a;
     1042      }
     1043    }
     1044  }
     1045
     1046  return new_dstr(p, list2(a, b));
     1047}
     1048
    7641049/* (:str . (s . len)) */
    7651050static node*
     
    7801065new_dsym(parser_state *p, node *a)
    7811066{
    782   return cons((node*)NODE_DSYM, new_dstr(p, a));
     1067  return cons((node*)NODE_DSYM, a);
    7831068}
    7841069
     
    10241309  if (p->parsing_heredoc == NULL) {
    10251310    p->lstate = EXPR_BEG;
    1026     p->cmd_start = TRUE;
    10271311    end_strterm(p);
    10281312    p->lex_strterm = p->lex_strterm_before_heredoc;
    10291313    p->lex_strterm_before_heredoc = NULL;
    1030     p->heredoc_end_now = TRUE;
    10311314  }
    10321315  else {
     
    11051388        keyword__ENCODING__
    11061389
    1107 %token <id>  tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
     1390%token <id>  tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL_TAG
    11081391%token <nd>  tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
    1109 %token <nd>  tSTRING tSTRING_PART tSTRING_MID tLABEL_END
     1392%token <nd>  tSTRING tSTRING_PART tSTRING_MID
    11101393%token <nd>  tNTH_REF tBACK_REF
    11111394%token <num> tREGEXP_END
    1112 
    1113 %type <nd> singleton string string_rep string_interp xstring regexp
     1395%token <num> tNUMPARAM
     1396
     1397%type <nd> singleton string string_fragment string_rep string_interp xstring regexp
    11141398%type <nd> literal numeric cpath symbol
    11151399%type <nd> top_compstmt top_stmts top_stmt
     
    11221406%type <nd> command_asgn command_rhs mrhs superclass block_call block_command
    11231407%type <nd> f_block_optarg f_block_opt
    1124 %type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
     1408%type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_margs
    11251409%type <nd> assoc_list assocs assoc undef_list backref for_var
    11261410%type <nd> block_param opt_block_param block_param_def f_opt
     
    11321416%type <nd> heredoc words symbols
    11331417%type <num> call_op call_op2     /* 0:'&.', 1:'.', 2:'::' */
     1418
     1419%type <nd> args_tail opt_args_tail f_kwarg f_kw f_kwrest
     1420%type <nd> f_block_kwarg f_block_kw block_args_tail opt_block_args_tail
     1421%type <id> f_label
    11341422
    11351423%token tUPLUS             /* unary+ */
     
    11581446%token tLBRACE_ARG        /* { */
    11591447%token tSTAR              /* * */
     1448%token tDSTAR             /* ** */
    11601449%token tAMPER             /* & */
    11611450%token tLAMBDA            /* -> */
     
    11791468%right '=' tOP_ASGN
    11801469%left modifier_rescue
    1181 %right '?' ':'
     1470%right '?' ':' tLABEL_TAG
    11821471%nonassoc tDOT2 tDOT3
    11831472%left  tOROP
     
    12371526                    {
    12381527                      $<nd>$ = local_switch(p);
     1528                      nvars_block(p);
    12391529                    }
    12401530                  '{' top_compstmt '}'
     
    12421532                      yyerror(p, "BEGIN not supported");
    12431533                      local_resume(p, $<nd>2);
     1534                      nvars_unnest(p);
    12441535                      $$ = 0;
    12451536                    }
     
    13591650                      $$ = new_op_asgn(p, $1, $2, $3);
    13601651                    }
    1361                 | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs
    1362                     {
    1363                       $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
     1652                | primary_value '[' opt_call_args ']' tOP_ASGN command_rhs
     1653                    {
     1654                      $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
    13641655                    }
    13651656                | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
     
    13851676                      $$ = new_begin(p, 0);
    13861677                    }
    1387                 ;
     1678                ;
    13881679
    13891680command_rhs     : command_call   %prec tOP_ASGN
     
    14391730                    {
    14401731                      local_nest(p);
     1732                      nvars_nest(p);
    14411733                    }
    14421734                  opt_block_param
     
    14461738                      $$ = new_block(p, $3, $4);
    14471739                      local_unnest(p);
     1740                      nvars_unnest(p);
    14481741                    }
    14491742                ;
     
    15881881                      assignable(p, $1);
    15891882                    }
    1590                 | primary_value '[' opt_call_args rbracket
    1591                     {
    1592                       $$ = new_call(p, $1, intern("[]",2), $3, '.');
     1883                | primary_value '[' opt_call_args ']'
     1884                    {
     1885                      $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
    15931886                    }
    15941887                | primary_value call_op tIDENTIFIER
     
    16271920                      assignable(p, $1);
    16281921                    }
    1629                 | primary_value '[' opt_call_args rbracket
    1630                     {
    1631                       $$ = new_call(p, $1, intern("[]",2), $3, '.');
     1922                | primary_value '[' opt_call_args ']'
     1923                    {
     1924                      $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
    16321925                    }
    16331926                | primary_value call_op tIDENTIFIER
     
    16591952                      backref_error(p, $1);
    16601953                      $$ = 0;
     1954                    }
     1955                | tNUMPARAM
     1956                    {
     1957                      yyerror(p, "can't assign to numbered parameter");
    16611958                    }
    16621959                ;
     
    17132010                ;
    17142011
    1715 op              : '|'           { $$ = intern_c('|');   }
    1716                 | '^'           { $$ = intern_c('^');   }
    1717                 | '&'           { $$ = intern_c('&');   }
    1718                 | tCMP          { $$ = intern("<=>",3); }
    1719                 | tEQ           { $$ = intern("==",2);  }
    1720                 | tEQQ          { $$ = intern("===",3); }
    1721                 | tMATCH        { $$ = intern("=~",2);  }
    1722                 | tNMATCH       { $$ = intern("!~",2);  }
    1723                 | '>'           { $$ = intern_c('>');   }
    1724                 | tGEQ          { $$ = intern(">=",2);  }
    1725                 | '<'           { $$ = intern_c('<');   }
    1726                 | tLEQ          { $$ = intern("<=",2);  }
    1727                 | tNEQ          { $$ = intern("!=",2);  }
    1728                 | tLSHFT        { $$ = intern("<<",2);  }
    1729                 | tRSHFT        { $$ = intern(">>",2);  }
    1730                 | '+'           { $$ = intern_c('+');   }
    1731                 | '-'           { $$ = intern_c('-');   }
    1732                 | '*'           { $$ = intern_c('*');   }
    1733                 | tSTAR         { $$ = intern_c('*');   }
    1734                 | '/'           { $$ = intern_c('/');   }
    1735                 | '%'           { $$ = intern_c('%');   }
    1736                 | tPOW          { $$ = intern("**",2);  }
    1737                 | '!'           { $$ = intern_c('!');   }
    1738                 | '~'           { $$ = intern_c('~');   }
    1739                 | tUPLUS        { $$ = intern("+@",2);  }
    1740                 | tUMINUS       { $$ = intern("-@",2);  }
    1741                 | tAREF         { $$ = intern("[]",2);  }
    1742                 | tASET         { $$ = intern("[]=",3); }
    1743                 | '`'           { $$ = intern_c('`');   }
     2012op              : '|'           { $$ = intern_lit("|");   }
     2013                | '^'           { $$ = intern_lit("^");   }
     2014                | '&'           { $$ = intern_lit("&");   }
     2015                | tCMP          { $$ = intern_lit("<=>"); }
     2016                | tEQ           { $$ = intern_lit("==");  }
     2017                | tEQQ          { $$ = intern_lit("==="); }
     2018                | tMATCH        { $$ = intern_lit("=~");  }
     2019                | tNMATCH       { $$ = intern_lit("!~");  }
     2020                | '>'           { $$ = intern_lit(">");   }
     2021                | tGEQ          { $$ = intern_lit(">=");  }
     2022                | '<'           { $$ = intern_lit("<");   }
     2023                | tLEQ          { $$ = intern_lit("<=");  }
     2024                | tNEQ          { $$ = intern_lit("!=");  }
     2025                | tLSHFT        { $$ = intern_lit("<<");  }
     2026                | tRSHFT        { $$ = intern_lit(">>");  }
     2027                | '+'           { $$ = intern_lit("+");   }
     2028                | '-'           { $$ = intern_lit("-");   }
     2029                | '*'           { $$ = intern_lit("*");   }
     2030                | tSTAR         { $$ = intern_lit("*");   }
     2031                | '/'           { $$ = intern_lit("/");   }
     2032                | '%'           { $$ = intern_lit("%");   }
     2033                | tPOW          { $$ = intern_lit("**");  }
     2034                | tDSTAR        { $$ = intern_lit("**");  }
     2035                | '!'           { $$ = intern_lit("!");   }
     2036                | '~'           { $$ = intern_lit("~");   }
     2037                | tUPLUS        { $$ = intern_lit("+@");  }
     2038                | tUMINUS       { $$ = intern_lit("-@");  }
     2039                | tAREF         { $$ = intern_lit("[]");  }
     2040                | tASET         { $$ = intern_lit("[]="); }
     2041                | '`'           { $$ = intern_lit("`");   }
    17442042                ;
    17452043
     
    17662064                      $$ = new_op_asgn(p, $1, $2, $3);
    17672065                    }
    1768                 | primary_value '[' opt_call_args rbracket tOP_ASGN arg_rhs
    1769                     {
    1770                       $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
     2066                | primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs
     2067                    {
     2068                      $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
    17712069                    }
    17722070                | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
     
    19252223                      $$ = new_if(p, cond($1), $3, $6);
    19262224                    }
     2225                | arg '?' arg opt_nl tLABEL_TAG arg
     2226                    {
     2227                      $$ = new_if(p, cond($1), $3, $6);
     2228                    }
    19272229                | primary
    19282230                    {
     
    19392241                | args comma assocs trailer
    19402242                    {
    1941                       $$ = push($1, new_hash(p, $3));
     2243                      $$ = push($1, new_kw_hash(p, $3));
    19422244                    }
    19432245                | assocs trailer
    19442246                    {
    1945                       $$ = cons(new_hash(p, $1), 0);
     2247                      $$ = cons(new_kw_hash(p, $1), 0);
    19462248                      NODE_LINENO($$, $1);
    19472249                    }
     
    19602262                ;
    19612263
    1962 paren_args      : '(' opt_call_args rparen
     2264paren_args      : '(' opt_call_args ')'
    19632265                    {
    19642266                      $$ = $2;
     
    19712273
    19722274opt_call_args   : none
    1973                 | call_args
    1974                 | args ','
     2275                | call_args opt_terms
     2276                | args comma
    19752277                    {
    19762278                      $$ = cons($1,0);
    19772279                      NODE_LINENO($$, $1);
    19782280                    }
    1979                 | args comma assocs ','
    1980                     {
    1981                       $$ = cons(push($1, new_hash(p, $3)), 0);
     2281                | args comma assocs comma
     2282                    {
     2283                      $$ = cons(push($1, new_kw_hash(p, $3)), 0);
    19822284                      NODE_LINENO($$, $1);
    19832285                    }
    1984                 | assocs ','
    1985                     {
    1986                       $$ = cons(list1(new_hash(p, $1)), 0);
     2286                | assocs comma
     2287                    {
     2288                      $$ = cons(list1(new_kw_hash(p, $1)), 0);
    19872289                      NODE_LINENO($$, $1);
    19882290                    }
     
    20022304                | assocs opt_block_arg
    20032305                    {
    2004                       $$ = cons(list1(new_hash(p, $1)), $2);
     2306                      $$ = cons(list1(new_kw_hash(p, $1)), $2);
    20052307                      NODE_LINENO($$, $1);
    20062308                    }
    20072309                | args comma assocs opt_block_arg
    20082310                    {
    2009                       $$ = cons(push($1, new_hash(p, $3)), $4);
     2311                      $$ = cons(push($1, new_kw_hash(p, $3)), $4);
    20102312                      NODE_LINENO($$, $1);
    20112313                    }
     
    20452347
    20462348comma           : ','
    2047                 | ','  heredoc_bodies
     2349                | ','  opt_nl heredoc_bodies
    20482350                ;
    20492351
     
    20962398                | var_ref
    20972399                | backref
     2400                | tNUMPARAM
     2401                    {
     2402                      $$ = new_nvar(p, $1);
     2403                    }
    20982404                | tFID
    20992405                    {
     
    22482554                        yyerror(p, "class definition in method body");
    22492555                      $<nd>$ = local_switch(p);
     2556                      nvars_block(p);
    22502557                    }
    22512558                  bodystmt
     
    22552562                      SET_LINENO($$, $1);
    22562563                      local_resume(p, $<nd>4);
     2564                      nvars_unnest(p);
    22572565                    }
    22582566                | keyword_class
     
    22652573                    {
    22662574                      $<nd>$ = cons(local_switch(p), nint(p->in_single));
     2575                      nvars_block(p);
    22672576                      p->in_single = 0;
    22682577                    }
     
    22732582                      SET_LINENO($$, $1);
    22742583                      local_resume(p, $<nd>6->car);
     2584                      nvars_unnest(p);
    22752585                      p->in_def = $<num>4;
    22762586                      p->in_single = intn($<nd>6->cdr);
     
    22822592                        yyerror(p, "module definition in method body");
    22832593                      $<nd>$ = local_switch(p);
     2594                      nvars_block(p);
    22842595                    }
    22852596                  bodystmt
     
    22892600                      SET_LINENO($$, $1);
    22902601                      local_resume(p, $<nd>3);
     2602                      nvars_unnest(p);
    22912603                    }
    22922604                | keyword_def fname
     
    22982610                      p->in_def++;
    22992611                      $<nd>$ = local_switch(p);
     2612                      nvars_block(p);
    23002613                    }
    23012614                  f_arglist
     
    23062619                      SET_LINENO($$, $1);
    23072620                      local_resume(p, $<nd>4);
     2621                      nvars_unnest(p);
    23082622                      p->in_def--;
    23092623                      p->cmdarg_stack = $<stack>3;
     
    23202634                      p->lstate = EXPR_ENDFN; /* force for args */
    23212635                      $<nd>$ = local_switch(p);
     2636                      nvars_block(p);
    23222637                    }
    23232638                  f_arglist
     
    23282643                      SET_LINENO($$, $1);
    23292644                      local_resume(p, $<nd>6);
     2645                      nvars_unnest(p);
    23302646                      p->in_single--;
    23312647                      p->cmdarg_stack = $<stack>4;
     
    23882704                ;
    23892705
    2390 f_marg          : f_norm_arg
    2391                     {
    2392                       $$ = new_arg(p, $1);
    2393                     }
    2394                 | tLPAREN f_margs rparen
    2395                     {
    2396                       $$ = new_masgn(p, $2, 0);
    2397                     }
    2398                 ;
    2399 
    2400 f_marg_list     : f_marg
    2401                     {
    2402                       $$ = list1($1);
    2403                     }
    2404                 | f_marg_list ',' f_marg
    2405                     {
    2406                       $$ = push($1, $3);
    2407                     }
    2408                 ;
    2409 
    2410 f_margs         : f_marg_list
     2706f_margs         : f_arg
    24112707                    {
    24122708                      $$ = list3($1,0,0);
    24132709                    }
    2414                 | f_marg_list ',' tSTAR f_norm_arg
     2710                | f_arg ',' tSTAR f_norm_arg
    24152711                    {
    24162712                      $$ = list3($1, new_arg(p, $4), 0);
    24172713                    }
    2418                 | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
     2714                | f_arg ',' tSTAR f_norm_arg ',' f_arg
    24192715                    {
    24202716                      $$ = list3($1, new_arg(p, $4), $6);
    24212717                    }
    2422                 | f_marg_list ',' tSTAR
    2423                     {
     2718                | f_arg ',' tSTAR
     2719                    {
     2720                      local_add_f(p, 0);
    24242721                      $$ = list3($1, (node*)-1, 0);
    24252722                    }
    2426                 | f_marg_list ',' tSTAR ',' f_marg_list
     2723                | f_arg ',' tSTAR ',' f_arg
    24272724                    {
    24282725                      $$ = list3($1, (node*)-1, $5);
     
    24322729                      $$ = list3(0, new_arg(p, $2), 0);
    24332730                    }
    2434                 | tSTAR f_norm_arg ',' f_marg_list
     2731                | tSTAR f_norm_arg ',' f_arg
    24352732                    {
    24362733                      $$ = list3(0, new_arg(p, $2), $4);
     
    24382735                | tSTAR
    24392736                    {
     2737                      local_add_f(p, 0);
    24402738                      $$ = list3(0, (node*)-1, 0);
    24412739                    }
    2442                 | tSTAR ',' f_marg_list
    2443                     {
    2444                       $$ = list3(0, (node*)-1, $3);
    2445                     }
    2446                 ;
    2447 
    2448 block_param     : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
     2740                | tSTAR ','
     2741                    {
     2742                      local_add_f(p, 0);
     2743                    }
     2744                  f_arg
     2745                    {
     2746                      $$ = list3(0, (node*)-1, $4);
     2747                    }
     2748                ;
     2749
     2750block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
     2751                    {
     2752                      $$ = new_args_tail(p, $1, $3, $4);
     2753                    }
     2754                | f_block_kwarg opt_f_block_arg
     2755                    {
     2756                      $$ = new_args_tail(p, $1, 0, $2);
     2757                    }
     2758                | f_kwrest opt_f_block_arg
     2759                    {
     2760                      $$ = new_args_tail(p, 0, $1, $2);
     2761                    }
     2762                | f_block_arg
     2763                    {
     2764                      $$ = new_args_tail(p, 0, 0, $1);
     2765                    }
     2766                ;
     2767
     2768opt_block_args_tail : ',' block_args_tail
     2769                    {
     2770                      $$ = $2;
     2771                    }
     2772                | /* none */
     2773                    {
     2774                      $$ = new_args_tail(p, 0, 0, 0);
     2775                    }
     2776                ;
     2777
     2778block_param     : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
    24492779                    {
    24502780                      $$ = new_args(p, $1, $3, $5, 0, $6);
    24512781                    }
    2452                 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
     2782                | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
    24532783                    {
    24542784                      $$ = new_args(p, $1, $3, $5, $7, $8);
    24552785                    }
    2456                 | f_arg ',' f_block_optarg opt_f_block_arg
     2786                | f_arg ',' f_block_optarg opt_block_args_tail
    24572787                    {
    24582788                      $$ = new_args(p, $1, $3, 0, 0, $4);
    24592789                    }
    2460                 | f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg
     2790                | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
    24612791                    {
    24622792                      $$ = new_args(p, $1, $3, 0, $5, $6);
    24632793                    }
    2464                 | f_arg ',' f_rest_arg opt_f_block_arg
     2794                | f_arg ',' f_rest_arg opt_block_args_tail
    24652795                    {
    24662796                      $$ = new_args(p, $1, 0, $3, 0, $4);
    24672797                    }
    2468                 | f_arg ','
    2469                     {
    2470                       $$ = new_args(p, $1, 0, 0, 0, 0);
    2471                     }
    2472                 | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
     2798                | f_arg ',' opt_block_args_tail
     2799                    {
     2800                      $$ = new_args(p, $1, 0, 0, 0, $3);
     2801                    }
     2802                | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
    24732803                    {
    24742804                      $$ = new_args(p, $1, 0, $3, $5, $6);
    24752805                    }
    2476                 | f_arg opt_f_block_arg
     2806                | f_arg opt_block_args_tail
    24772807                    {
    24782808                      $$ = new_args(p, $1, 0, 0, 0, $2);
    24792809                    }
    2480                 | f_block_optarg ',' f_rest_arg opt_f_block_arg
     2810                | f_block_optarg ',' f_rest_arg opt_block_args_tail
    24812811                    {
    24822812                      $$ = new_args(p, 0, $1, $3, 0, $4);
    24832813                    }
    2484                 | f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
     2814                | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
    24852815                    {
    24862816                      $$ = new_args(p, 0, $1, $3, $5, $6);
    24872817                    }
    2488                 | f_block_optarg opt_f_block_arg
     2818                | f_block_optarg opt_block_args_tail
    24892819                    {
    24902820                      $$ = new_args(p, 0, $1, 0, 0, $2);
    24912821                    }
    2492                 | f_block_optarg ',' f_arg opt_f_block_arg
     2822                | f_block_optarg ',' f_arg opt_block_args_tail
    24932823                    {
    24942824                      $$ = new_args(p, 0, $1, 0, $3, $4);
    24952825                    }
    2496                 | f_rest_arg opt_f_block_arg
     2826                | f_rest_arg opt_block_args_tail
    24972827                    {
    24982828                      $$ = new_args(p, 0, 0, $1, 0, $2);
    24992829                    }
    2500                 | f_rest_arg ',' f_arg opt_f_block_arg
     2830                | f_rest_arg ',' f_arg opt_block_args_tail
    25012831                    {
    25022832                      $$ = new_args(p, 0, 0, $1, $3, $4);
    25032833                    }
    2504                 | f_block_arg
     2834                | block_args_tail
    25052835                    {
    25062836                      $$ = new_args(p, 0, 0, 0, 0, $1);
     
    25092839
    25102840opt_block_param : none
     2841                    {
     2842                      local_add_blk(p, 0);
     2843                      $$ = 0;
     2844                    }
    25112845                | block_param_def
    2512                     {
     2846                   {
    25132847                      p->cmd_start = TRUE;
    25142848                      $$ = $1;
     
    25162850                ;
    25172851
    2518 block_param_def : '|' opt_bv_decl '|'
     2852block_param_def : '|' {local_add_blk(p, 0);} opt_bv_decl '|'
    25192853                    {
    25202854                      $$ = 0;
     
    25222856                | tOROP
    25232857                    {
     2858                      local_add_blk(p, 0);
    25242859                      $$ = 0;
    25252860                    }
     
    25672902                      $$ = $2;
    25682903                    }
    2569                 | keyword_do_LAMBDA compstmt keyword_end
     2904                | keyword_do_LAMBDA bodystmt keyword_end
    25702905                    {
    25712906                      $$ = $2;
     
    25762911                    {
    25772912                      local_nest(p);
     2913                      nvars_nest(p);
    25782914                    }
    25792915                  opt_block_param
    2580                   compstmt
     2916                  bodystmt
    25812917                  keyword_end
    25822918                    {
    25832919                      $$ = new_block(p,$3,$4);
    25842920                      local_unnest(p);
     2921                      nvars_unnest(p);
    25852922                    }
    25862923                ;
     
    26302967                | primary_value call_op paren_args
    26312968                    {
    2632                       $$ = new_call(p, $1, intern("call",4), $3, $2);
     2969                      $$ = new_call(p, $1, intern_lit("call"), $3, $2);
    26332970                    }
    26342971                | primary_value tCOLON2 paren_args
    26352972                    {
    2636                       $$ = new_call(p, $1, intern("call",4), $3, tCOLON2);
     2973                      $$ = new_call(p, $1, intern_lit("call"), $3, tCOLON2);
    26372974                    }
    26382975                | keyword_super paren_args
     
    26442981                      $$ = new_zsuper(p);
    26452982                    }
    2646                 | primary_value '[' opt_call_args rbracket
    2647                     {
    2648                       $$ = new_call(p, $1, intern("[]",2), $3, '.');
     2983                | primary_value '[' opt_call_args ']'
     2984                    {
     2985                      $$ = new_call(p, $1, intern_lit("[]"), $3, '.');
    26492986                    }
    26502987                ;
     
    26532990                    {
    26542991                      local_nest(p);
     2992                      nvars_nest(p);
    26552993                      $<num>$ = p->lineno;
    26562994                    }
     
    26612999                      SET_LINENO($$, $<num>2);
    26623000                      local_unnest(p);
     3001                      nvars_unnest(p);
    26633002                    }
    26643003                | keyword_do
    26653004                    {
    26663005                      local_nest(p);
     3006                      nvars_nest(p);
    26673007                      $<num>$ = p->lineno;
    26683008                    }
    26693009                  opt_block_param
    2670                   compstmt keyword_end
     3010                  bodystmt keyword_end
    26713011                    {
    26723012                      $$ = new_block(p,$3,$4);
    26733013                      SET_LINENO($$, $<num>2);
    26743014                      local_unnest(p);
     3015                      nvars_unnest(p);
    26753016                    }
    26763017                ;
     
    27343075                ;
    27353076
    2736 string          : tCHAR
     3077string          : string_fragment
     3078                | string string_fragment
     3079                    {
     3080                      $$ = concat_string(p, $1, $2);
     3081                    }
     3082                ;
     3083
     3084string_fragment : tCHAR
    27373085                | tSTRING
    27383086                | tSTRING_BEG tSTRING
     
    28543202symbol          : basic_symbol
    28553203                    {
     3204                      p->lstate = EXPR_ENDARG;
    28563205                      $$ = new_sym(p, $1);
    28573206                    }
    28583207                | tSYMBEG tSTRING_BEG string_rep tSTRING
    28593208                    {
    2860                       p->lstate = EXPR_END;
    2861                       $$ = new_dsym(p, push($3, $4));
     3209                      p->lstate = EXPR_ENDARG;
     3210                      $$ = new_dsym(p, new_dstr(p, push($3, $4)));
    28623211                    }
    28633212                ;
     
    28653214basic_symbol    : tSYMBEG sym
    28663215                    {
    2867                       p->lstate = EXPR_END;
    28683216                      $$ = $2;
    28693217                    }
     
    29323280                      assignable(p, $1);
    29333281                    }
     3282                | tNUMPARAM
     3283                    {
     3284                      yyerror(p, "can't assign to numbered parameter");
     3285                    }
    29343286                ;
    29353287
     
    29563308                | keyword__FILE__
    29573309                    {
    2958                       const char *fn = p->filename;
     3310                      const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
    29593311                      if (!fn) {
    29603312                        fn = "(null)";
     
    29663318                      char buf[16];
    29673319
    2968                       snprintf(buf, sizeof(buf), "%d", p->lineno);
    2969                       $$ = new_int(p, buf, 10);
     3320                      dump_int(p->lineno, buf);
     3321                      $$ = new_int(p, buf, 10, 0);
     3322                    }
     3323                | keyword__ENCODING__
     3324                    {
     3325#ifdef MRB_UTF8_STRING
     3326                      const char *enc = "UTF-8";
     3327#else
     3328                      const char *enc = "ASCII-8BIT";
     3329#endif
     3330                      $$ = new_str(p, enc, strlen(enc));
    29703331                    }
    29713332                ;
     
    30073368                ;
    30083369
    3009 f_args          : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
     3370f_label         : tIDENTIFIER tLABEL_TAG
     3371                    {
     3372                      local_nest(p);
     3373                    }
     3374                ;
     3375
     3376f_kw            : f_label arg
     3377                    {
     3378                      void_expr_error(p, $2);
     3379                      $$ = new_kw_arg(p, $1, cons($2, locals_node(p)));
     3380                      local_unnest(p);
     3381                    }
     3382                | f_label
     3383                    {
     3384                      $$ = new_kw_arg(p, $1, 0);
     3385                      local_unnest(p);
     3386                    }
     3387                ;
     3388
     3389f_block_kw      : f_label primary_value
     3390                    {
     3391                      $$ = new_kw_arg(p, $1, cons($2, locals_node(p)));
     3392                      local_unnest(p);
     3393                    }
     3394                | f_label
     3395                    {
     3396                      $$ = new_kw_arg(p, $1, 0);
     3397                      local_unnest(p);
     3398                    }
     3399                ;
     3400
     3401f_block_kwarg   : f_block_kw
     3402                    {
     3403                      $$ = list1($1);
     3404                    }
     3405                | f_block_kwarg ',' f_block_kw
     3406                    {
     3407                      $$ = push($1, $3);
     3408                    }
     3409                ;
     3410
     3411f_kwarg         : f_kw
     3412                    {
     3413                      $$ = list1($1);
     3414                    }
     3415                | f_kwarg ',' f_kw
     3416                    {
     3417                      $$ = push($1, $3);
     3418                    }
     3419                ;
     3420
     3421kwrest_mark     : tPOW
     3422                | tDSTAR
     3423                ;
     3424
     3425f_kwrest        : kwrest_mark tIDENTIFIER
     3426                    {
     3427                      $$ = cons((node*)NODE_KW_REST_ARGS, nsym($2));
     3428                    }
     3429                | kwrest_mark
     3430                    {
     3431                      $$ = cons((node*)NODE_KW_REST_ARGS, 0);
     3432                    }
     3433                ;
     3434
     3435args_tail       : f_kwarg ',' f_kwrest opt_f_block_arg
     3436                    {
     3437                      $$ = new_args_tail(p, $1, $3, $4);
     3438                    }
     3439                | f_kwarg opt_f_block_arg
     3440                    {
     3441                      $$ = new_args_tail(p, $1, 0, $2);
     3442                    }
     3443                | f_kwrest opt_f_block_arg
     3444                    {
     3445                      $$ = new_args_tail(p, 0, $1, $2);
     3446                    }
     3447                | f_block_arg
     3448                    {
     3449                      $$ = new_args_tail(p, 0, 0, $1);
     3450                    }
     3451                ;
     3452
     3453opt_args_tail   : ',' args_tail
     3454                    {
     3455                      $$ = $2;
     3456                    }
     3457                | /* none */
     3458                    {
     3459                      $$ = new_args_tail(p, 0, 0, 0);
     3460                    }
     3461                ;
     3462
     3463f_args          : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
    30103464                    {
    30113465                      $$ = new_args(p, $1, $3, $5, 0, $6);
    30123466                    }
    3013                 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
     3467                | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
    30143468                    {
    30153469                      $$ = new_args(p, $1, $3, $5, $7, $8);
    30163470                    }
    3017                 | f_arg ',' f_optarg opt_f_block_arg
     3471                | f_arg ',' f_optarg opt_args_tail
    30183472                    {
    30193473                      $$ = new_args(p, $1, $3, 0, 0, $4);
    30203474                    }
    3021                 | f_arg ',' f_optarg ',' f_arg opt_f_block_arg
     3475                | f_arg ',' f_optarg ',' f_arg opt_args_tail
    30223476                    {
    30233477                      $$ = new_args(p, $1, $3, 0, $5, $6);
    30243478                    }
    3025                 | f_arg ',' f_rest_arg opt_f_block_arg
     3479                | f_arg ',' f_rest_arg opt_args_tail
    30263480                    {
    30273481                      $$ = new_args(p, $1, 0, $3, 0, $4);
    30283482                    }
    3029                 | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
     3483                | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
    30303484                    {
    30313485                      $$ = new_args(p, $1, 0, $3, $5, $6);
    30323486                    }
    3033                 | f_arg opt_f_block_arg
     3487                | f_arg opt_args_tail
    30343488                    {
    30353489                      $$ = new_args(p, $1, 0, 0, 0, $2);
    30363490                    }
    3037                 | f_optarg ',' f_rest_arg opt_f_block_arg
     3491                | f_optarg ',' f_rest_arg opt_args_tail
    30383492                    {
    30393493                      $$ = new_args(p, 0, $1, $3, 0, $4);
    30403494                    }
    3041                 | f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
     3495                | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
    30423496                    {
    30433497                      $$ = new_args(p, 0, $1, $3, $5, $6);
    30443498                    }
    3045                 | f_optarg opt_f_block_arg
     3499                | f_optarg opt_args_tail
    30463500                    {
    30473501                      $$ = new_args(p, 0, $1, 0, 0, $2);
    30483502                    }
    3049                 | f_optarg ',' f_arg opt_f_block_arg
     3503                | f_optarg ',' f_arg opt_args_tail
    30503504                    {
    30513505                      $$ = new_args(p, 0, $1, 0, $3, $4);
    30523506                    }
    3053                 | f_rest_arg opt_f_block_arg
     3507                | f_rest_arg opt_args_tail
    30543508                    {
    30553509                      $$ = new_args(p, 0, 0, $1, 0, $2);
    30563510                    }
    3057                 | f_rest_arg ',' f_arg opt_f_block_arg
     3511                | f_rest_arg ',' f_arg opt_args_tail
    30583512                    {
    30593513                      $$ = new_args(p, 0, 0, $1, $3, $4);
    30603514                    }
    3061                 | f_block_arg
     3515                | args_tail
    30623516                    {
    30633517                      $$ = new_args(p, 0, 0, 0, 0, $1);
     
    30653519                | /* none */
    30663520                    {
    3067                       local_add_f(p, 0);
     3521                      local_add_f(p, mrb_intern_lit(p->mrb, "&"));
    30683522                      $$ = new_args(p, 0, 0, 0, 0, 0);
    30693523                    }
     
    30903544                      $$ = 0;
    30913545                    }
     3546                | tNUMPARAM
     3547                    {
     3548                      yyerror(p, "formal argument cannot be a numbered parameter");
     3549                      $$ = 0;
     3550                    }
    30923551                ;
    30933552
     
    31073566                      $$ = new_arg(p, $1);
    31083567                    }
    3109                 | tLPAREN f_margs rparen
    3110                     {
    3111                       $$ = new_masgn(p, $2, 0);
     3568                | tLPAREN
     3569                    {
     3570                      $<nd>$ = local_switch(p);
     3571                    }
     3572                  f_margs rparen
     3573                    {
     3574                      $$ = new_masgn_param(p, $3, p->locals->car);
     3575                      local_resume(p, $<nd>2);
     3576                      local_add_f(p, 0);
    31123577                    }
    31133578                ;
     
    31263591                    {
    31273592                      local_add_f(p, $1);
     3593                      local_nest(p);
    31283594                      $$ = $1;
    31293595                    }
     
    31333599                    {
    31343600                      void_expr_error(p, $2);
    3135                       $$ = cons(nsym($1), $2);
     3601                      $$ = cons(nsym($1), cons($2, locals_node(p)));
     3602                      local_unnest(p);
    31363603                    }
    31373604                ;
     
    31403607                    {
    31413608                      void_expr_error(p, $2);
    3142                       $$ = cons(nsym($1), $2);
     3609                      $$ = cons(nsym($1), cons($2, locals_node(p)));
     3610                      local_unnest(p);
    31433611                    }
    31443612                ;
     
    31753643                | restarg_mark
    31763644                    {
    3177                       local_add_f(p, 0);
     3645                      local_add_f(p, mrb_intern_lit(p->mrb, "*"));
    31783646                      $$ = -1;
    31793647                    }
     
    31863654f_block_arg     : blkarg_mark tIDENTIFIER
    31873655                    {
    3188                       local_add_f(p, $2);
    31893656                      $$ = $2;
    31903657                    }
     
    31973664                | none
    31983665                    {
    3199                       local_add_f(p, 0);
    32003666                      $$ = 0;
    32013667                    }
     
    32443710                      NODE_LINENO($$, $1);
    32453711                    }
    3246                 | assocs ',' assoc
     3712                | assocs comma assoc
    32473713                    {
    32483714                      $$ = push($1, $3);
    32493715                    }
     3716                ;
     3717
     3718label_tag       : tLABEL_TAG
     3719                | tLABEL_TAG heredoc_bodies
    32503720                ;
    32513721
     
    32563726                      $$ = cons($1, $3);
    32573727                    }
    3258                 | tLABEL arg
     3728                | tIDENTIFIER label_tag arg
     3729                    {
     3730                      void_expr_error(p, $3);
     3731                      $$ = cons(new_sym(p, $1), $3);
     3732                    }
     3733                | string_fragment label_tag arg
     3734                    {
     3735                      void_expr_error(p, $3);
     3736                      if ($1->car == (node*)NODE_DSTR) {
     3737                        $$ = cons(new_dsym(p, $1), $3);
     3738                      }
     3739                      else {
     3740                        $$ = cons(new_sym(p, new_strsym(p, $1)), $3);
     3741                      }
     3742                    }
     3743                | tDSTAR arg
    32593744                    {
    32603745                      void_expr_error(p, $2);
    3261                       $$ = cons(new_sym(p, $1), $2);
    3262                     }
    3263                 | tLABEL_END arg
    3264                     {
    3265                       void_expr_error(p, $2);
    3266                       $$ = cons(new_sym(p, new_strsym(p, $1)), $2);
    3267                     }
    3268                 | tSTRING_BEG tLABEL_END arg
    3269                     {
    3270                       void_expr_error(p, $3);
    3271                       $$ = cons(new_sym(p, new_strsym(p, $2)), $3);
    3272                     }
    3273                 | tSTRING_BEG string_rep tLABEL_END arg
    3274                     {
    3275                       void_expr_error(p, $4);
    3276                       $$ = cons(new_dsym(p, push($2, $3)), $4);
     3746                      $$ = cons(cons((node*)NODE_KW_REST_ARGS, 0), $2);
    32773747                    }
    32783748                ;
     
    33233793                ;
    33243794
    3325 rparen          : opt_nl ')'
    3326                 ;
    3327 
    3328 rbracket        : opt_nl ']'
     3795rparen          : opt_terms ')'
    33293796                ;
    33303797
    33313798trailer         : /* none */
    3332                 | nl
     3799                | terms
    33333800                | comma
    33343801                ;
     
    33623829{
    33633830  char* c;
    3364   int n;
     3831  size_t n;
    33653832
    33663833  if (! p->capture_errors) {
    33673834#ifndef MRB_DISABLE_STDIO
    3368     if (p->filename) {
    3369       fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
     3835    if (p->filename_sym) {
     3836      const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
     3837      fprintf(stderr, "%s:%d:%d: %s\n", filename, p->lineno, p->column, s);
    33703838    }
    33713839    else {
     
    33863854
    33873855static void
    3388 yyerror_i(parser_state *p, const char *fmt, int i)
     3856yyerror_c(parser_state *p, const char *msg, char c)
    33893857{
    33903858  char buf[256];
    33913859
    3392   snprintf(buf, sizeof(buf), fmt, i);
     3860  strncpy(buf, msg, sizeof(buf) - 2);
     3861  buf[sizeof(buf) - 2] = '\0';
     3862  strncat(buf, &c, 1);
    33933863  yyerror(p, buf);
    33943864}
     
    33983868{
    33993869  char* c;
    3400   int n;
     3870  size_t n;
    34013871
    34023872  if (! p->capture_errors) {
    34033873#ifndef MRB_DISABLE_STDIO
    3404     if (p->filename) {
    3405       fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
     3874    if (p->filename_sym) {
     3875      const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
     3876      fprintf(stderr, "%s:%d:%d: warning: %s\n", filename, p->lineno, p->column, s);
    34063877    }
    34073878    else {
    3408       fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);
     3879      fprintf(stderr, "line %d:%d: warning: %s\n", p->lineno, p->column, s);
    34093880    }
    34103881#endif
     
    34283899
    34293900static void
    3430 yywarning_s(parser_state *p, const char *fmt, const char *s)
     3901yywarning_s(parser_state *p, const char *msg, const char *s)
    34313902{
    34323903  char buf[256];
    34333904
    3434   snprintf(buf, sizeof(buf), fmt, s);
     3905  strncpy(buf, msg, sizeof(buf) - 1);
     3906  buf[sizeof(buf) - 1] = '\0';
     3907  strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1);
     3908  strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
    34353909  yywarning(p, buf);
    34363910}
     
    34413915  int c;
    34423916
    3443   c = (int)(intptr_t)n->car;
     3917  c = intn(n->car);
    34443918
    34453919  if (c == NODE_NTH_REF) {
    3446     yyerror_i(p, "can't set variable $%" MRB_PRId, (mrb_int)(intptr_t)n->cdr);
     3920    yyerror_c(p, "can't set variable $", (char)intn(n->cdr)+'0');
    34473921  }
    34483922  else if (c == NODE_BACK_REF) {
    3449     yyerror_i(p, "can't set variable $%c", (int)(intptr_t)n->cdr);
     3923    yyerror_c(p, "can't set variable $", (char)intn(n->cdr));
    34503924  }
    34513925  else {
    3452     mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %S", mrb_fixnum_value(c));
     3926    mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c);
    34533927  }
    34543928}
     
    34603934
    34613935  if (n == NULL) return;
    3462   c = (int)(intptr_t)n->car;
     3936  c = intn(n->car);
    34633937  switch (c) {
    34643938  case NODE_BREAK:
     
    34713945  case NODE_AND:
    34723946  case NODE_OR:
    3473     void_expr_error(p, n->cdr->car);
    3474     void_expr_error(p, n->cdr->cdr);
     3947    if (n->cdr) {
     3948      void_expr_error(p, n->cdr->car);
     3949      void_expr_error(p, n->cdr->cdr);
     3950    }
    34753951    break;
    34763952  case NODE_BEGIN:
     
    34923968
    34933969static inline int
     3970nextc0(parser_state *p)
     3971{
     3972  int c;
     3973#ifndef MRB_DISABLE_STDIO
     3974  if (p->f) {
     3975    if (feof(p->f)) return -1;
     3976    c = fgetc(p->f);
     3977    if (c == EOF) return -1;
     3978  }
     3979  else
     3980#endif
     3981    if (!p->s || p->s >= p->send) {
     3982      return -1;
     3983    }
     3984    else {
     3985      c = (unsigned char)*p->s++;
     3986    }
     3987  return c;
     3988}
     3989
     3990static inline int
    34943991nextc(parser_state *p)
    34953992{
     
    34993996    node *tmp;
    35003997
    3501     c = (int)(intptr_t)p->pb->car;
     3998    c = intn(p->pb->car);
    35023999    tmp = p->pb;
    35034000    p->pb = p->pb->cdr;
     
    35054002  }
    35064003  else {
    3507 #ifndef MRB_DISABLE_STDIO
    3508     if (p->f) {
    3509       if (feof(p->f)) goto eof;
    3510       c = fgetc(p->f);
    3511       if (c == EOF) goto eof;
    3512     }
    3513     else
    3514 #endif
    3515       if (!p->s || p->s >= p->send) {
    3516         goto eof;
    3517       }
    3518       else {
    3519         c = (unsigned char)*p->s++;
    3520       }
     4004    c = nextc0(p);
     4005    if (c < 0) goto eof;
    35214006  }
    35224007  if (c >= 0) {
     
    35244009  }
    35254010  if (c == '\r') {
    3526     c = nextc(p);
    3527     if (c != '\n') {
    3528       pushback(p, c);
    3529       return '\r';
    3530     }
    3531     return c;
     4011    const int lf = nextc0(p);
     4012    if (lf == '\n') {
     4013      return '\n';
     4014    }
     4015    if (lf > 0) pushback(p, lf);
    35324016  }
    35334017  return c;
     
    35484032    p->column--;
    35494033  }
    3550   p->pb = cons((node*)(intptr_t)c, p->pb);
     4034  p->pb = cons(nint(c), p->pb);
    35514035}
    35524036
     
    35734057    if (c0 == -1) return c0;    /* do not skip partial EOF */
    35744058    if (c0 >= 0) --p->column;
    3575     list = push(list, (node*)(intptr_t)c0);
     4059    list = push(list, nint(c0));
    35764060  } while(n--);
    35774061  if (p->pb) {
     
    35944078peeks(parser_state *p, const char *s)
    35954079{
    3596   int len = strlen(s);
     4080  size_t len = strlen(s);
    35974081
    35984082#ifndef MRB_DISABLE_STDIO
     
    36304114    s++;
    36314115    if (peeks(p, s)) {
    3632       int len = strlen(s);
     4116      size_t len = strlen(s);
    36334117
    36344118      while (len--) {
     
    37524236#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
    37534237
    3754 static int
     4238static int32_t
    37554239scan_oct(const int *start, int len, int *retlen)
    37564240{
    37574241  const int *s = start;
    3758   int retval = 0;
     4242  int32_t retval = 0;
    37594243
    37604244  /* mrb_assert(len <= 3) */
     
    37634247    retval |= *s++ - '0';
    37644248  }
    3765   *retlen = s - start;
     4249  *retlen = (int)(s - start);
    37664250
    37674251  return retval;
     
    37694253
    37704254static int32_t
    3771 scan_hex(const int *start, int len, int *retlen)
     4255scan_hex(parser_state *p, const int *start, int len, int *retlen)
    37724256{
    37734257  static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
    37744258  const int *s = start;
    3775   int32_t retval = 0;
     4259  uint32_t retval = 0;
    37764260  char *tmp;
    37774261
     
    37824266    s++;
    37834267  }
    3784   *retlen = s - start;
    3785 
    3786   return retval;
     4268  *retlen = (int)(s - start);
     4269
     4270  return (int32_t)retval;
    37874271}
    37884272
     
    37904274read_escape_unicode(parser_state *p, int limit)
    37914275{
    3792   int32_t c;
    37934276  int buf[9];
    37944277  int i;
     4278  int32_t hex;
    37954279
    37964280  /* Look for opening brace */
    37974281  i = 0;
    37984282  buf[0] = nextc(p);
    3799   if (buf[0] < 0) goto eof;
     4283  if (buf[0] < 0) {
     4284  eof:
     4285    yyerror(p, "invalid escape character syntax");
     4286    return -1;
     4287  }
    38004288  if (ISXDIGIT(buf[0])) {
    38014289    /* \uxxxx form */
     
    38124300    pushback(p, buf[0]);
    38134301  }
    3814   c = scan_hex(buf, i, &i);
    3815   if (i == 0) {
    3816   eof:
    3817     yyerror(p, "Invalid escape character syntax");
     4302  hex = scan_hex(p, buf, i, &i);
     4303  if (i == 0 || hex > 0x10FFFF || (hex & 0xFFFFF800) == 0xD800) {
     4304    yyerror(p, "invalid Unicode code point");
    38184305    return -1;
    38194306  }
    3820   if (c < 0 || c > 0x10FFFF || (c & 0xFFFFF800) == 0xD800) {
    3821     yyerror(p, "Invalid Unicode code point");
    3822     return -1;
    3823   }
    3824   return c;
     4307  return hex;
    38254308}
    38264309
     
    38884371      }
    38894372    }
    3890     c = scan_hex(buf, i, &i);
    38914373    if (i == 0) {
    3892       yyerror(p, "Invalid escape character syntax");
    3893       return 0;
    3894     }
    3895   }
    3896   return c;
     4374      yyerror(p, "invalid hex escape");
     4375      return -1;
     4376    }
     4377    return scan_hex(p, buf, i, &i);
     4378  }
    38974379
    38984380  case 'u':     /* Unicode */
     
    39614443  int c;
    39624444  string_type type = (string_type)(intptr_t)p->lex_strterm->car;
    3963   int nest_level = (intptr_t)p->lex_strterm->cdr->car;
    3964   int beg = (intptr_t)p->lex_strterm->cdr->cdr->car;
    3965   int end = (intptr_t)p->lex_strterm->cdr->cdr->cdr;
     4445  int nest_level = intn(p->lex_strterm->cdr->car);
     4446  int beg = intn(p->lex_strterm->cdr->cdr->car);
     4447  int end = intn(p->lex_strterm->cdr->cdr->cdr);
    39664448  parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL;
    3967   int cmd_state = p->cmd_start;
    39684449
    39694450  if (beg == 0) beg = -3;       /* should never happen */
     
    39904471        }
    39914472        if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
    3992           if (c < 0) {
    3993             p->parsing_heredoc = NULL;
    3994           }
    3995           else {
    3996             return tHEREDOC_END;
    3997           }
     4473          return tHEREDOC_END;
    39984474        }
    39994475      }
    40004476      if (c < 0) {
    40014477        char buf[256];
    4002         snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term);
    4003         yyerror(p, buf);
     4478        const char s1[] = "can't find heredoc delimiter \"";
     4479        const char s2[] = "\" anywhere before EOF";
     4480
     4481        if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) {
     4482          yyerror(p, "can't find heredoc delimiter anywhere before EOF");
     4483        } else {
     4484          strcpy(buf, s1);
     4485          strcat(buf, hinf->term);
     4486          strcat(buf, s2);
     4487          yyerror(p, buf);
     4488        }
    40044489        return 0;
    40054490      }
     
    40134498    else if (c == beg) {
    40144499      nest_level++;
    4015       p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;
     4500      p->lex_strterm->cdr->car = nint(nest_level);
    40164501    }
    40174502    else if (c == end) {
    40184503      nest_level--;
    4019       p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;
     4504      p->lex_strterm->cdr->car = nint(nest_level);
    40204505    }
    40214506    else if (c == '\\') {
     
    41194604
    41204605  tokfix(p);
    4121   p->lstate = EXPR_END;
     4606  p->lstate = EXPR_ENDARG;
    41224607  end_strterm(p);
    41234608
     
    41454630      case 'u': f |= 16; break;
    41464631      case 'n': f |= 32; break;
     4632      case 'o': break;
    41474633      default: tokadd(p, re_opt); break;
    41484634      }
     
    41514637    if (toklen(p)) {
    41524638      char msg[128];
     4639
     4640      strcpy(msg, "unknown regexp option");
    41534641      tokfix(p);
    4154       snprintf(msg, sizeof(msg), "unknown regexp option%s - %s",
    4155           toklen(p) > 1 ? "s" : "", tok(p));
     4642      if (toklen(p) > 1) {
     4643        strcat(msg, "s");
     4644      }
     4645      strcat(msg, " - ");
     4646      strncat(msg, tok(p), sizeof(msg) - strlen(msg) - 1);
    41564647      yyerror(p, msg);
    41574648    }
     
    41804671  }
    41814672  pylval.nd = new_str(p, tok(p), toklen(p));
    4182   if (IS_LABEL_POSSIBLE()) {
    4183     if (IS_LABEL_SUFFIX(0)) {
    4184       p->lstate = EXPR_BEG;
    4185       nextc(p);
    4186       return tLABEL_END;
    4187     }
    4188   }
    41894673
    41904674  return tSTRING;
    41914675}
    41924676
     4677static int
     4678number_literal_suffix(parser_state *p)
     4679{
     4680  int c, result = 0;
     4681  node *list = 0;
     4682  int column = p->column;
     4683  int mask = NUM_SUFFIX_R|NUM_SUFFIX_I;
     4684
     4685  while ((c = nextc(p)) != -1) {
     4686    list = push(list, (node*)(intptr_t)c);
     4687
     4688    if ((mask & NUM_SUFFIX_I) && c == 'i') {
     4689      result |= (mask & NUM_SUFFIX_I);
     4690      mask &= ~NUM_SUFFIX_I;
     4691      /* r after i, rational of complex is disallowed */
     4692      mask &= ~NUM_SUFFIX_R;
     4693      continue;
     4694    }
     4695    if ((mask & NUM_SUFFIX_R) && c == 'r') {
     4696      result |= (mask & NUM_SUFFIX_R);
     4697      mask &= ~NUM_SUFFIX_R;
     4698      continue;
     4699    }
     4700    if (!ISASCII(c) || ISALPHA(c) || c == '_') {
     4701      p->column = column;
     4702      if (p->pb) {
     4703        p->pb = append((node*)list, p->pb);
     4704      }
     4705      else {
     4706        p->pb = list;
     4707      }
     4708      return 0;
     4709    }
     4710    pushback(p, c);
     4711    break;
     4712  }
     4713  return result;
     4714}
    41934715
    41944716static int
     
    43114833  case -2:      /* end of a file */
    43124834  case '\n':
    4313     maybe_heredoc:
     4835  maybe_heredoc:
    43144836    heredoc_treat_nextline(p);
    4315   switch (p->lstate) {
    4316   case EXPR_BEG:
    4317   case EXPR_FNAME:
    4318   case EXPR_DOT:
    4319   case EXPR_CLASS:
    4320   case EXPR_VALUE:
    4321     p->lineno++;
    43224837    p->column = 0;
     4838    switch (p->lstate) {
     4839    case EXPR_BEG:
     4840    case EXPR_FNAME:
     4841    case EXPR_DOT:
     4842    case EXPR_CLASS:
     4843    case EXPR_VALUE:
     4844      p->lineno++;
     4845      if (p->parsing_heredoc != NULL) {
     4846        if (p->lex_strterm) {
     4847          return parse_string(p);
     4848        }
     4849      }
     4850      goto retry;
     4851    default:
     4852      break;
     4853    }
    43234854    if (p->parsing_heredoc != NULL) {
    4324       if (p->lex_strterm) {
    4325         return parse_string(p);
    4326       }
    4327     }
    4328     goto retry;
    4329   default:
    4330     break;
    4331   }
    4332   if (p->parsing_heredoc != NULL) {
     4855      return '\n';
     4856    }
     4857    while ((c = nextc(p))) {
     4858      switch (c) {
     4859      case ' ': case '\t': case '\f': case '\r':
     4860      case '\13': /* '\v' */
     4861        space_seen = 1;
     4862        break;
     4863      case '#': /* comment as a whitespace */
     4864        pushback(p, '#');
     4865        p->lineno++;
     4866        goto retry;
     4867      case '.':
     4868        if (!peek(p, '.')) {
     4869          pushback(p, '.');
     4870          p->lineno++;
     4871          goto retry;
     4872        }
     4873        pushback(p, c);
     4874        goto normal_newline;
     4875      case '&':
     4876        if (peek(p, '.')) {
     4877          pushback(p, '&');
     4878          p->lineno++;
     4879          goto retry;
     4880        }
     4881        pushback(p, c);
     4882        goto normal_newline;
     4883      case -1:                  /* EOF */
     4884      case -2:                  /* end of a file */
     4885        goto normal_newline;
     4886      default:
     4887        pushback(p, c);
     4888        goto normal_newline;
     4889      }
     4890    }
     4891  normal_newline:
     4892    p->cmd_start = TRUE;
     4893    p->lstate = EXPR_BEG;
    43334894    return '\n';
    4334   }
    4335   while ((c = nextc(p))) {
    4336     switch (c) {
    4337     case ' ': case '\t': case '\f': case '\r':
    4338     case '\13': /* '\v' */
    4339       space_seen = 1;
    4340       break;
    4341     case '.':
    4342       if ((c = nextc(p)) != '.') {
    4343         pushback(p, c);
    4344         pushback(p, '.');
    4345         goto retry;
    4346       }
    4347     case -1:                  /* EOF */
    4348     case -2:                  /* end of a file */
    4349       goto normal_newline;
    4350     default:
    4351       pushback(p, c);
    4352       goto normal_newline;
    4353     }
    4354   }
    4355   normal_newline:
    4356   p->cmd_start = TRUE;
    4357   p->lstate = EXPR_BEG;
    4358   return '\n';
    43594895
    43604896  case '*':
    43614897    if ((c = nextc(p)) == '*') {
    43624898      if ((c = nextc(p)) == '=') {
    4363         pylval.id = intern("**",2);
     4899        pylval.id = intern_lit("**");
    43644900        p->lstate = EXPR_BEG;
    43654901        return tOP_ASGN;
    43664902      }
    43674903      pushback(p, c);
    4368       c = tPOW;
     4904      if (IS_SPCARG(c)) {
     4905        yywarning(p, "'**' interpreted as argument prefix");
     4906        c = tDSTAR;
     4907      }
     4908      else if (IS_BEG()) {
     4909        c = tDSTAR;
     4910      }
     4911      else {
     4912        c = tPOW; /* "**", "argument prefix" */
     4913      }
    43694914    }
    43704915    else {
    43714916      if (c == '=') {
    4372         pylval.id = intern_c('*');
     4917        pylval.id = intern_lit("*");
    43734918        p->lstate = EXPR_BEG;
    43744919        return tOP_ASGN;
     
    44865031    if (c == '<') {
    44875032      if ((c = nextc(p)) == '=') {
    4488         pylval.id = intern("<<",2);
     5033        pylval.id = intern_lit("<<");
    44895034        p->lstate = EXPR_BEG;
    44905035        return tOP_ASGN;
     
    45085053    if (c == '>') {
    45095054      if ((c = nextc(p)) == '=') {
    4510         pylval.id = intern(">>",2);
     5055        pylval.id = intern_lit(">>");
    45115056        p->lstate = EXPR_BEG;
    45125057        return tOP_ASGN;
     
    45795124        if (c2) {
    45805125          char buf[256];
    4581           snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
     5126          char cc[] = { (char)c2, '\0' };
     5127
     5128          strcpy(buf, "invalid character syntax; use ?\\");
     5129          strncat(buf, cc, 2);
    45825130          yyerror(p, buf);
    45835131        }
     
    45905138    newtok(p);
    45915139    /* need support UTF-8 if configured */
    4592     if ((isalnum(c) || c == '_')) {
     5140    if ((ISALNUM(c) || c == '_')) {
    45935141      int c2 = nextc(p);
    45945142      pushback(p, c2);
    4595       if ((isalnum(c2) || c2 == '_')) {
     5143      if ((ISALNUM(c2) || c2 == '_')) {
    45965144        goto ternary;
    45975145      }
     
    46065154    tokfix(p);
    46075155    pylval.nd = new_str(p, tok(p), toklen(p));
    4608     p->lstate = EXPR_END;
     5156    p->lstate = EXPR_ENDARG;
    46095157    return tCHAR;
    46105158
     
    46135161      p->lstate = EXPR_BEG;
    46145162      if ((c = nextc(p)) == '=') {
    4615         pylval.id = intern("&&",2);
     5163        pylval.id = intern_lit("&&");
    46165164        p->lstate = EXPR_BEG;
    46175165        return tOP_ASGN;
     
    46255173    }
    46265174    else if (c == '=') {
    4627       pylval.id = intern_c('&');
     5175      pylval.id = intern_lit("&");
    46285176      p->lstate = EXPR_BEG;
    46295177      return tOP_ASGN;
     
    46525200      p->lstate = EXPR_BEG;
    46535201      if ((c = nextc(p)) == '=') {
    4654         pylval.id = intern("||",2);
     5202        pylval.id = intern_lit("||");
    46555203        p->lstate = EXPR_BEG;
    46565204        return tOP_ASGN;
     
    46605208    }
    46615209    if (c == '=') {
    4662       pylval.id = intern_c('|');
     5210      pylval.id = intern_lit("|");
    46635211      p->lstate = EXPR_BEG;
    46645212      return tOP_ASGN;
     
    46845232    }
    46855233    if (c == '=') {
    4686       pylval.id = intern_c('+');
     5234      pylval.id = intern_lit("+");
    46875235      p->lstate = EXPR_BEG;
    46885236      return tOP_ASGN;
     
    47125260    }
    47135261    if (c == '=') {
    4714       pylval.id = intern_c('-');
     5262      pylval.id = intern_lit("-");
    47155263      p->lstate = EXPR_BEG;
    47165264      return tOP_ASGN;
     
    47535301  {
    47545302    int is_float, seen_point, seen_e, nondigit;
     5303    int suffix = 0;
    47555304
    47565305    is_float = seen_point = seen_e = nondigit = 0;
    4757     p->lstate = EXPR_END;
     5306    p->lstate = EXPR_ENDARG;
    47585307    newtok(p);
    47595308    if (c == '-' || c == '+') {
     
    47865335        }
    47875336        else if (nondigit) goto trailing_uc;
    4788         pylval.nd = new_int(p, tok(p), 16);
     5337        suffix = number_literal_suffix(p);
     5338        pylval.nd = new_int(p, tok(p), 16, suffix);
    47895339        return tINTEGER;
    47905340      }
     
    48105360        }
    48115361        else if (nondigit) goto trailing_uc;
    4812         pylval.nd = new_int(p, tok(p), 2);
     5362        suffix = number_literal_suffix(p);
     5363        pylval.nd = new_int(p, tok(p), 2, suffix);
    48135364        return tINTEGER;
    48145365      }
     
    48345385        }
    48355386        else if (nondigit) goto trailing_uc;
    4836         pylval.nd = new_int(p, tok(p), 10);
     5387        suffix = number_literal_suffix(p);
     5388        pylval.nd = new_int(p, tok(p), 10, suffix);
    48375389        return tINTEGER;
    48385390      }
     
    48675419          tokfix(p);
    48685420          if (nondigit) goto trailing_uc;
    4869           pylval.nd = new_int(p, tok(p), 8);
     5421          suffix = number_literal_suffix(p);
     5422          pylval.nd = new_int(p, tok(p), 8, suffix);
    48705423          return tINTEGER;
    48715424        }
     
    48845437      else {
    48855438        pushback(p, c);
    4886         pylval.nd = new_int(p, "0", 10);
     5439        suffix = number_literal_suffix(p);
     5440        pylval.nd = new_int(p, "0", 10, suffix);
    48875441        return tINTEGER;
    48885442      }
     
    49525506    if (nondigit) {
    49535507      trailing_uc:
    4954       yyerror_i(p, "trailing '%c' in number", nondigit);
     5508      yyerror_c(p, "trailing non digit in number: ", (char)nondigit);
    49555509    }
    49565510    tokfix(p);
    49575511    if (is_float) {
     5512#ifdef MRB_WITHOUT_FLOAT
     5513      yywarning_s(p, "floating point numbers are not supported", tok(p));
     5514      pylval.nd = new_int(p, "0", 10, 0);
     5515      return tINTEGER;
     5516#else
    49585517      double d;
    49595518      char *endp;
     
    49625521      d = mrb_float_read(tok(p), &endp);
    49635522      if (d == 0 && endp == tok(p)) {
    4964         yywarning_s(p, "corrupted float value %s", tok(p));
     5523        yywarning_s(p, "corrupted float value", tok(p));
    49655524      }
    49665525      else if (errno == ERANGE) {
    4967         yywarning_s(p, "float %s out of range", tok(p));
     5526        yywarning_s(p, "float out of range", tok(p));
    49685527        errno = 0;
    49695528      }
    4970       pylval.nd = new_float(p, tok(p));
     5529      suffix = number_literal_suffix(p);
     5530      pylval.nd = new_float(p, tok(p), suffix);
    49715531      return tFLOAT;
    4972     }
    4973     pylval.nd = new_int(p, tok(p), 10);
     5532#endif
     5533    }
     5534    suffix = number_literal_suffix(p);
     5535    pylval.nd = new_int(p, tok(p), 10, suffix);
    49745536    return tINTEGER;
    49755537  }
     
    49855547      p->lstate = EXPR_ENDFN;
    49865548    else
    4987       p->lstate = EXPR_ENDARG;
     5549      p->lstate = EXPR_END;
    49885550    return c;
    49895551
     
    49985560      return tCOLON2;
    49995561    }
    5000     if (IS_END() || ISSPACE(c)) {
     5562    if (!space_seen && IS_END()) {
    50015563      pushback(p, c);
    50025564      p->lstate = EXPR_BEG;
    5003       return ':';
     5565      return tLABEL_TAG;
     5566    }
     5567    if (!ISSPACE(c) || IS_BEG()) {
     5568      pushback(p, c);
     5569      p->lstate = EXPR_FNAME;
     5570      return tSYMBEG;
    50045571    }
    50055572    pushback(p, c);
    5006     p->lstate = EXPR_FNAME;
    5007     return tSYMBEG;
     5573    p->lstate = EXPR_BEG;
     5574    return ':';
    50085575
    50095576  case '/':
     
    50135580    }
    50145581    if ((c = nextc(p)) == '=') {
    5015       pylval.id = intern_c('/');
     5582      pylval.id = intern_lit("/");
    50165583      p->lstate = EXPR_BEG;
    50175584      return tOP_ASGN;
     
    50325599  case '^':
    50335600    if ((c = nextc(p)) == '=') {
    5034       pylval.id = intern_c('^');
     5601      pylval.id = intern_lit("^");
    50355602      p->lstate = EXPR_BEG;
    50365603      return tOP_ASGN;
     
    50705637    }
    50715638    else if (IS_SPCARG(-1)) {
     5639      c = tLPAREN_ARG;
     5640    }
     5641    else if (p->lstate == EXPR_END && space_seen) {
    50725642      c = tLPAREN_ARG;
    50735643    }
     
    51475717      else {
    51485718        term = nextc(p);
    5149         if (isalnum(term)) {
     5719        if (ISALNUM(term)) {
    51505720          yyerror(p, "unknown type of %string");
    51515721          return 0;
     
    52065776    }
    52075777    if ((c = nextc(p)) == '=') {
    5208       pylval.id = intern_c('%');
     5778      pylval.id = intern_lit("%");
    52095779      p->lstate = EXPR_BEG;
    52105780      return tOP_ASGN;
     
    52605830      tokadd(p, c);
    52615831      tokfix(p);
    5262       pylval.id = intern_cstr(tok(p));
     5832      pylval.id = intern(tok(p), toklen(p));
    52635833      return tGVAR;
    52645834
     
    52705840      gvar:
    52715841      tokfix(p);
    5272       pylval.id = intern_cstr(tok(p));
     5842      pylval.id = intern(tok(p), toklen(p));
    52735843      return tGVAR;
    52745844
     
    52915861        tokadd(p, c);
    52925862        c = nextc(p);
    5293       } while (c >= 0 && isdigit(c));
     5863      } while (c >= 0 && ISDIGIT(c));
    52945864      pushback(p, c);
    52955865      if (last_state == EXPR_FNAME) goto gvar;
     
    52985868        unsigned long n = strtoul(tok(p), NULL, 10);
    52995869        if (n > INT_MAX) {
    5300           yyerror_i(p, "capture group index must be <= %d", INT_MAX);
     5870          yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX));
    53015871          return 0;
    53025872        }
     
    53335903        return 0;
    53345904      }
    5335       else if (isdigit(c)) {
     5905      else if (ISDIGIT(c)) {
    53365906        if (p->tidx == 1) {
    5337           yyerror_i(p, "'@%c' is not allowed as an instance variable name", c);
     5907          yyerror_c(p, "wrong instance variable name: @", c);
    53385908        }
    53395909        else {
    5340           yyerror_i(p, "'@@%c' is not allowed as a class variable name", c);
     5910          yyerror_c(p, "wrong class variable name: @@", c);
    53415911        }
    53425912        return 0;
     
    53545924    default:
    53555925      if (!identchar(c)) {
    5356         yyerror_i(p,  "Invalid char '\\x%02X' in expression", c);
     5926        char buf[36];
     5927        const char s[] = "Invalid char in expression: 0x";
     5928        const char hexdigits[] = "0123456789ABCDEF";
     5929
     5930        strcpy(buf, s);
     5931        buf[sizeof(s)-1] = hexdigits[(c & 0xf0) >> 4];
     5932        buf[sizeof(s)]   = hexdigits[(c & 0x0f)];
     5933        buf[sizeof(s)+1] = 0;
     5934        yyerror(p, buf);
    53575935        goto retry;
    53585936      }
     
    54005978      break;
    54015979
     5980    case '_':
     5981      if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) {
     5982        int n = tok(p)[1] - '0';
     5983        int nvar;
     5984
     5985        if (n > 0) {
     5986          node *nvars = p->nvars->cdr;
     5987
     5988          while (nvars) {
     5989            nvar = intn(nvars->car);
     5990            if (nvar == -2) break; /* top of the scope */
     5991            if (nvar > 0) {
     5992              yywarning(p, "numbered parameter used in outer block");
     5993              break;
     5994            }
     5995            nvars->car = nint(-1);
     5996            nvars = nvars->cdr;
     5997          }
     5998          nvar = intn(p->nvars->car);
     5999          if (nvar == -1) {
     6000            yywarning(p, "numbered parameter used in inner block");
     6001          }
     6002          if (nvar >= -1) {
     6003            pylval.num = n;
     6004            p->lstate = EXPR_END;
     6005            return tNUMPARAM;
     6006          }
     6007          else {
     6008            yywarning(p, "identifier for numbered parameter; consider another name");
     6009          }
     6010        }
     6011      }
     6012      /* fall through */
    54026013    default:
    54036014      if (toklast(p) == '!' || toklast(p) == '?') {
     
    54066017      else {
    54076018        if (p->lstate == EXPR_FNAME) {
     6019          if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
     6020              (!peek(p, '=') || (peek_n(p, '>', 1)))) {
     6021            result = tIDENTIFIER;
     6022            tokadd(p, c);
     6023            tokfix(p);
     6024          }
     6025          else {
     6026            pushback(p, c);
     6027          }
    54086028          if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
    54096029              (!peek(p, '=') || (peek_n(p, '>', 1)))) {
     
    54266046      if (IS_LABEL_POSSIBLE()) {
    54276047        if (IS_LABEL_SUFFIX(0)) {
    5428           p->lstate = EXPR_BEG;
    5429           nextc(p);
     6048          p->lstate = EXPR_END;
    54306049          tokfix(p);
    5431           pylval.id = intern_cstr(tok(p));
    5432           return tLABEL;
     6050          pylval.id = intern(tok(p), toklen(p));
     6051          return tIDENTIFIER;
    54336052        }
    54346053      }
     
    54886107    }
    54896108    {
    5490       mrb_sym ident = intern_cstr(tok(p));
     6109      mrb_sym ident = intern(tok(p), toklen(p));
    54916110
    54926111      pylval.id = ident;
    5493 #if 0
    5494       if (last_state != EXPR_DOT && islower(tok(p)[0]) && lvar_defined(ident)) {
     6112      if (last_state != EXPR_DOT && ISLOWER(tok(p)[0]) && local_var_p(p, ident)) {
    54956113        p->lstate = EXPR_END;
    54966114      }
    5497 #endif
    54986115    }
    54996116    return result;
     
    55246141  p->capture_errors = cxt->capture_errors;
    55256142  p->no_optimize = cxt->no_optimize;
     6143  p->on_eval = cxt->on_eval;
    55266144  if (cxt->partial_hook) {
    55276145    p->cxt = cxt;
     
    55366154
    55376155  if (!cxt) return;
    5538   if ((int)(intptr_t)p->tree->car != NODE_SCOPE) return;
     6156  if (intn(p->tree->car) != NODE_SCOPE) return;
    55396157  n0 = n = p->tree->cdr->car;
    55406158  while (n) {
     
    55596177
    55606178  MRB_TRY(p->jmp) {
    5561     int n;
     6179    int n = 1;
    55626180
    55636181    p->cmd_start = TRUE;
     
    56756293{
    56766294  if (s) {
    5677     int len = strlen(s);
     6295    size_t len = strlen(s);
    56786296    char *p = (char *)mrb_malloc(mrb, len + 1);
    56796297
     
    57026320
    57036321  sym = mrb_intern_cstr(p->mrb, f);
    5704   p->filename = mrb_sym2name_len(p->mrb, sym, NULL);
     6322  p->filename_sym = sym;
    57056323  p->lineno = (p->filename_table_length > 0)? 0 : 1;
    57066324
    57076325  for (i = 0; i < p->filename_table_length; ++i) {
    57086326    if (p->filename_table[i] == sym) {
    5709       p->current_filename_index = i;
     6327      p->current_filename_index = (int)i;
    57106328      return;
    57116329    }
    57126330  }
    57136331
     6332  if (p->filename_table_length == UINT16_MAX) {
     6333    yyerror(p, "too many files to compile");
     6334    return;
     6335  }
    57146336  p->current_filename_index = p->filename_table_length++;
    57156337
    57166338  new_table = (mrb_sym*)parser_palloc(p, sizeof(mrb_sym) * p->filename_table_length);
    57176339  if (p->filename_table) {
    5718     memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->filename_table_length);
     6340    memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->current_filename_index);
    57196341  }
    57206342  p->filename_table = new_table;
     
    57226344}
    57236345
    5724 MRB_API char const*
     6346MRB_API mrb_sym
    57256347mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
    5726   if (idx >= p->filename_table_length) { return NULL; }
     6348  if (idx >= p->filename_table_length) return 0;
    57276349  else {
    5728     return mrb_sym2name_len(p->mrb, p->filename_table[idx], NULL);
     6350    return p->filename_table[idx];
    57296351  }
    57306352}
     
    57476369
    57486370MRB_API parser_state*
    5749 mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c)
     6371mrb_parse_nstring(mrb_state *mrb, const char *s, size_t len, mrbc_context *c)
    57506372{
    57516373  parser_state *p;
     
    57786400  }
    57796401  if (!p->tree || p->nerr) {
     6402    if (c) c->parser_nerr = p->nerr;
    57806403    if (p->capture_errors) {
    57816404      char buf[256];
    5782       int n;
    5783 
    5784       n = snprintf(buf, sizeof(buf), "line %d: %s\n",
    5785           p->error_buffer[0].lineno, p->error_buffer[0].message);
    5786       mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
     6405
     6406      strcpy(buf, "line ");
     6407      dump_int(p->error_buffer[0].lineno, buf+5);
     6408      strcat(buf, ": ");
     6409      strncat(buf, p->error_buffer[0].message, sizeof(buf) - strlen(buf) - 1);
     6410      mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, strlen(buf)));
    57876411      mrb_parser_free(p);
    57886412      return mrb_undef_value();
     
    58176441    }
    58186442  }
    5819   proc->target_class = target;
     6443  MRB_PROC_SET_TARGET_CLASS(proc, target);
    58206444  if (mrb->c->ci) {
    58216445    mrb->c->ci->target_class = target;
     
    58416465
    58426466MRB_API mrb_value
    5843 mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c)
     6467mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *c)
    58446468{
    58456469  return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
     
    58476471
    58486472MRB_API mrb_value
    5849 mrb_load_nstring(mrb_state *mrb, const char *s, int len)
     6473mrb_load_nstring(mrb_state *mrb, const char *s, size_t len)
    58506474{
    58516475  return mrb_load_nstring_cxt(mrb, s, len, NULL);
     
    58856509}
    58866510
     6511static void
     6512dump_args(mrb_state *mrb, node *n, int offset)
     6513{
     6514  if (n->car) {
     6515    dump_prefix(n, offset+1);
     6516    printf("mandatory args:\n");
     6517    dump_recur(mrb, n->car, offset+2);
     6518  }
     6519  n = n->cdr;
     6520  if (n->car) {
     6521    dump_prefix(n, offset+1);
     6522    printf("optional args:\n");
     6523    {
     6524      node *n2 = n->car;
     6525
     6526      while (n2) {
     6527        dump_prefix(n2, offset+2);
     6528        printf("%s=\n", mrb_sym_name(mrb, sym(n2->car->car)));
     6529        mrb_parser_dump(mrb, n2->car->cdr, offset+3);
     6530        n2 = n2->cdr;
     6531      }
     6532    }
     6533  }
     6534  n = n->cdr;
     6535  if (n->car) {
     6536    dump_prefix(n, offset+1);
     6537    printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car)));
     6538  }
     6539  n = n->cdr;
     6540  if (n->car) {
     6541    dump_prefix(n, offset+1);
     6542    printf("post mandatory args:\n");
     6543    dump_recur(mrb, n->car, offset+2);
     6544  }
     6545
     6546  n = n->cdr;
     6547  if (n) {
     6548    mrb_assert(intn(n->car) == NODE_ARGS_TAIL);
     6549    mrb_parser_dump(mrb, n, offset);
     6550  }
     6551}
     6552
     6553/*
     6554 * This function restores the GC arena on return.
     6555 * For this reason, if a process that further generates an object is
     6556 * performed at the caller, the string pointer returned as the return
     6557 * value may become invalid.
     6558 */
     6559static const char*
     6560str_dump(mrb_state *mrb, const char *str, int len)
     6561{
     6562  mrb_int ai = mrb_gc_arena_save(mrb);
     6563  mrb_value s;
     6564# if INT_MAX > MRB_INT_MAX / 4
     6565  /* check maximum length with "\xNN" charactor */
     6566  if (len > MRB_INT_MAX / 4) {
     6567    len = MRB_INT_MAX / 4;
     6568  }
     6569# endif
     6570  s = mrb_str_new(mrb, str, (mrb_int)len);
     6571  s = mrb_str_dump(mrb, s);
     6572  mrb_gc_arena_restore(mrb, ai);
     6573  return RSTRING_PTR(s);
     6574}
    58876575#endif
    58886576
     
    58966584  again:
    58976585  dump_prefix(tree, offset);
    5898   nodetype = (int)(intptr_t)tree->car;
     6586  nodetype = intn(tree->car);
    58996587  tree = tree->cdr;
    59006588  switch (nodetype) {
     
    59566644
    59576645  case NODE_LAMBDA:
    5958     printf("NODE_BLOCK:\n");
     6646    printf("NODE_LAMBDA:\n");
     6647    dump_prefix(tree, offset);
    59596648    goto block;
    59606649
     
    59646653    tree = tree->cdr;
    59656654    if (tree->car) {
    5966       node *n = tree->car;
    5967 
    5968       if (n->car) {
    5969         dump_prefix(n, offset+1);
    5970         printf("mandatory args:\n");
    5971         dump_recur(mrb, n->car, offset+2);
    5972       }
    5973       n = n->cdr;
    5974       if (n->car) {
    5975         dump_prefix(n, offset+1);
    5976         printf("optional args:\n");
    5977         {
    5978           node *n2 = n->car;
    5979 
    5980           while (n2) {
    5981             dump_prefix(n2, offset+2);
    5982             printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
    5983             mrb_parser_dump(mrb, n2->car->cdr, 0);
    5984             n2 = n2->cdr;
    5985           }
    5986         }
    5987       }
    5988       n = n->cdr;
    5989       if (n->car) {
    5990         dump_prefix(n, offset+1);
    5991         printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
    5992       }
    5993       n = n->cdr;
    5994       if (n->car) {
    5995         dump_prefix(n, offset+1);
    5996         printf("post mandatory args:\n");
    5997         dump_recur(mrb, n->car, offset+2);
    5998       }
    5999       if (n->cdr) {
    6000         dump_prefix(n, offset+1);
    6001         printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr)));
    6002       }
     6655      dump_args(mrb, tree->car, offset+1);
    60036656    }
    60046657    dump_prefix(tree, offset+1);
     
    61236776          if (n2->car) {
    61246777            if (!first_lval) printf(", ");
    6125             printf("%s", mrb_sym2name(mrb, sym(n2->car)));
     6778            printf("%s", mrb_sym_name(mrb, sym(n2->car)));
    61266779            first_lval = FALSE;
    61276780          }
     
    61516804    dump_prefix(tree, offset+1);
    61526805    printf("method='%s' (%d)\n",
    6153         mrb_sym2name(mrb, sym(tree->cdr->car)),
    6154         (int)(intptr_t)tree->cdr->car);
     6806        mrb_sym_dump(mrb, sym(tree->cdr->car)),
     6807        intn(tree->cdr->car));
    61556808    tree = tree->cdr->cdr->car;
    61566809    if (tree) {
     
    61826835    mrb_parser_dump(mrb, tree->car, offset+1);
    61836836    dump_prefix(tree, offset+1);
    6184     printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr)));
     6837    printf("::%s\n", mrb_sym_name(mrb, sym(tree->cdr)));
    61856838    break;
    61866839
    61876840  case NODE_COLON3:
    6188     printf("NODE_COLON3: ::%s\n", mrb_sym2name(mrb, sym(tree)));
     6841    printf("NODE_COLON3: ::%s\n", mrb_sym_name(mrb, sym(tree)));
    61896842    break;
    61906843
     
    61966849  case NODE_HASH:
    61976850    printf("NODE_HASH:\n");
     6851    while (tree) {
     6852      dump_prefix(tree, offset+1);
     6853      printf("key:\n");
     6854      mrb_parser_dump(mrb, tree->car->car, offset+2);
     6855      dump_prefix(tree, offset+1);
     6856      printf("value:\n");
     6857      mrb_parser_dump(mrb, tree->car->cdr, offset+2);
     6858      tree = tree->cdr;
     6859    }
     6860    break;
     6861
     6862  case NODE_KW_HASH:
     6863    printf("NODE_KW_HASH:\n");
    61986864    while (tree) {
    61996865      dump_prefix(tree, offset+1);
     
    62696935    tree = tree->cdr;
    62706936    dump_prefix(tree, offset+1);
    6271     printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), (int)(intptr_t)tree->car);
     6937    printf("op='%s' (%d)\n", mrb_sym_name(mrb, sym(tree->car)), intn(tree->car));
    62726938    tree = tree->cdr;
    62736939    mrb_parser_dump(mrb, tree->car, offset+1);
     
    63216987
    63226988  case NODE_LVAR:
    6323     printf("NODE_LVAR %s\n", mrb_sym2name(mrb, sym(tree)));
     6989    printf("NODE_LVAR %s\n", mrb_sym_name(mrb, sym(tree)));
    63246990    break;
    63256991
    63266992  case NODE_GVAR:
    6327     printf("NODE_GVAR %s\n", mrb_sym2name(mrb, sym(tree)));
     6993    printf("NODE_GVAR %s\n", mrb_sym_name(mrb, sym(tree)));
    63286994    break;
    63296995
    63306996  case NODE_IVAR:
    6331     printf("NODE_IVAR %s\n", mrb_sym2name(mrb, sym(tree)));
     6997    printf("NODE_IVAR %s\n", mrb_sym_name(mrb, sym(tree)));
    63326998    break;
    63336999
    63347000  case NODE_CVAR:
    6335     printf("NODE_CVAR %s\n", mrb_sym2name(mrb, sym(tree)));
     7001    printf("NODE_CVAR %s\n", mrb_sym_name(mrb, sym(tree)));
     7002    break;
     7003
     7004  case NODE_NVAR:
     7005    printf("NODE_NVAR %d\n", intn(tree));
    63367006    break;
    63377007
    63387008  case NODE_CONST:
    6339     printf("NODE_CONST %s\n", mrb_sym2name(mrb, sym(tree)));
     7009    printf("NODE_CONST %s\n", mrb_sym_name(mrb, sym(tree)));
    63407010    break;
    63417011
     
    63517021
    63527022  case NODE_BACK_REF:
    6353     printf("NODE_BACK_REF: $%c\n", (int)(intptr_t)tree);
     7023    printf("NODE_BACK_REF: $%c\n", intn(tree));
    63547024    break;
    63557025
    63567026  case NODE_NTH_REF:
    6357     printf("NODE_NTH_REF: $%" MRB_PRId "\n", (mrb_int)(intptr_t)tree);
     7027    printf("NODE_NTH_REF: $%d\n", intn(tree));
    63587028    break;
    63597029
    63607030  case NODE_ARG:
    6361     printf("NODE_ARG %s\n", mrb_sym2name(mrb, sym(tree)));
     7031    printf("NODE_ARG %s\n", mrb_sym_name(mrb, sym(tree)));
    63627032    break;
    63637033
     
    63687038
    63697039  case NODE_INT:
    6370     printf("NODE_INT %s base %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr->car);
     7040    printf("NODE_INT %s base %d\n", (char*)tree->car, intn(tree->cdr->car));
    63717041    break;
    63727042
     
    63767046
    63777047  case NODE_NEGATE:
    6378     printf("NODE_NEGATE\n");
     7048    printf("NODE_NEGATE:\n");
    63797049    mrb_parser_dump(mrb, tree, offset+1);
    63807050    break;
    63817051
    63827052  case NODE_STR:
    6383     printf("NODE_STR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);
     7053    printf("NODE_STR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
    63847054    break;
    63857055
    63867056  case NODE_DSTR:
    6387     printf("NODE_DSTR\n");
     7057    printf("NODE_DSTR:\n");
    63887058    dump_recur(mrb, tree, offset+1);
    63897059    break;
    63907060
    63917061  case NODE_XSTR:
    6392     printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);
     7062    printf("NODE_XSTR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
    63937063    break;
    63947064
    63957065  case NODE_DXSTR:
    6396     printf("NODE_DXSTR\n");
     7066    printf("NODE_DXSTR:\n");
    63977067    dump_recur(mrb, tree, offset+1);
    63987068    break;
     
    64037073
    64047074  case NODE_DREGX:
    6405     printf("NODE_DREGX\n");
     7075    printf("NODE_DREGX:\n");
    64067076    dump_recur(mrb, tree->car, offset+1);
    64077077    dump_prefix(tree, offset);
     
    64187088
    64197089  case NODE_SYM:
    6420     printf("NODE_SYM :%s (%d)\n", mrb_sym2name(mrb, sym(tree)),
    6421            (int)(intptr_t)tree);
     7090    printf("NODE_SYM :%s (%d)\n", mrb_sym_dump(mrb, sym(tree)),
     7091           intn(tree));
     7092    break;
     7093
     7094  case NODE_DSYM:
     7095    printf("NODE_DSYM:\n");
     7096    mrb_parser_dump(mrb, tree, offset+1);
     7097    break;
     7098
     7099  case NODE_WORDS:
     7100    printf("NODE_WORDS:\n");
     7101    dump_recur(mrb, tree, offset+1);
     7102    break;
     7103
     7104  case NODE_SYMBOLS:
     7105    printf("NODE_SYMBOLS:\n");
     7106    dump_recur(mrb, tree, offset+1);
     7107    break;
     7108
     7109  case NODE_LITERAL_DELIM:
     7110    printf("NODE_LITERAL_DELIM\n");
    64227111    break;
    64237112
     
    64407129  case NODE_ALIAS:
    64417130    printf("NODE_ALIAS %s %s:\n",
    6442         mrb_sym2name(mrb, sym(tree->car)),
    6443         mrb_sym2name(mrb, sym(tree->cdr)));
     7131        mrb_sym_dump(mrb, sym(tree->car)),
     7132        mrb_sym_dump(mrb, sym(tree->cdr)));
    64447133    break;
    64457134
     
    64497138      node *t = tree;
    64507139      while (t) {
    6451         printf(" %s", mrb_sym2name(mrb, sym(t->car)));
     7140        printf(" %s", mrb_sym_dump(mrb, sym(t->car)));
    64527141        t = t->cdr;
    64537142      }
     
    64607149    if (tree->car->car == (node*)0) {
    64617150      dump_prefix(tree, offset+1);
    6462       printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
     7151      printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
    64637152    }
    64647153    else if (tree->car->car == (node*)1) {
    64657154      dump_prefix(tree, offset+1);
    6466       printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
     7155      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
    64677156    }
    64687157    else {
    64697158      mrb_parser_dump(mrb, tree->car->car, offset+1);
    64707159      dump_prefix(tree, offset+1);
    6471       printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
     7160      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
    64727161    }
    64737162    if (tree->cdr->car) {
     
    64857174    if (tree->car->car == (node*)0) {
    64867175      dump_prefix(tree, offset+1);
    6487       printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
     7176      printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
    64887177    }
    64897178    else if (tree->car->car == (node*)1) {
    64907179      dump_prefix(tree, offset+1);
    6491       printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
     7180      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
    64927181    }
    64937182    else {
    64947183      mrb_parser_dump(mrb, tree->car->car, offset+1);
    64957184      dump_prefix(tree, offset+1);
    6496       printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
     7185      printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
    64977186    }
    64987187    dump_prefix(tree, offset+1);
     
    65127201    printf("NODE_DEF:\n");
    65137202    dump_prefix(tree, offset+1);
    6514     printf("%s\n", mrb_sym2name(mrb, sym(tree->car)));
     7203    printf("%s\n", mrb_sym_dump(mrb, sym(tree->car)));
    65157204    tree = tree->cdr;
    65167205    {
     
    65257214          if (n2->car) {
    65267215            if (!first_lval) printf(", ");
    6527             printf("%s", mrb_sym2name(mrb, sym(n2->car)));
     7216            printf("%s", mrb_sym_name(mrb, sym(n2->car)));
    65287217            first_lval = FALSE;
    65297218          }
     
    65357224    tree = tree->cdr;
    65367225    if (tree->car) {
    6537       node *n = tree->car;
    6538 
    6539       if (n->car) {
    6540         dump_prefix(n, offset+1);
    6541         printf("mandatory args:\n");
    6542         dump_recur(mrb, n->car, offset+2);
    6543       }
    6544       n = n->cdr;
    6545       if (n->car) {
    6546         dump_prefix(n, offset+1);
    6547         printf("optional args:\n");
    6548         {
    6549           node *n2 = n->car;
    6550 
    6551           while (n2) {
    6552             dump_prefix(n2, offset+2);
    6553             printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
    6554             mrb_parser_dump(mrb, n2->car->cdr, 0);
    6555             n2 = n2->cdr;
    6556           }
    6557         }
    6558       }
    6559       n = n->cdr;
    6560       if (n->car) {
    6561         dump_prefix(n, offset+1);
    6562         printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
    6563       }
    6564       n = n->cdr;
    6565       if (n->car) {
    6566         dump_prefix(n, offset+1);
    6567         printf("post mandatory args:\n");
    6568         dump_recur(mrb, n->car, offset+2);
    6569       }
    6570       if (n->cdr) {
    6571         dump_prefix(n, offset+1);
    6572         printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr)));
    6573       }
     7226      dump_args(mrb, tree->car, offset);
    65747227    }
    65757228    mrb_parser_dump(mrb, tree->cdr->car, offset+1);
     
    65817234    tree = tree->cdr;
    65827235    dump_prefix(tree, offset+1);
    6583     printf(":%s\n", mrb_sym2name(mrb, sym(tree->car)));
     7236    printf(":%s\n", mrb_sym_dump(mrb, sym(tree->car)));
    65847237    tree = tree->cdr->cdr;
    65857238    if (tree->car) {
    6586       node *n = tree->car;
    6587 
    6588       if (n->car) {
    6589         dump_prefix(n, offset+1);
    6590         printf("mandatory args:\n");
    6591         dump_recur(mrb, n->car, offset+2);
    6592       }
    6593       n = n->cdr;
    6594       if (n->car) {
    6595         dump_prefix(n, offset+1);
    6596         printf("optional args:\n");
    6597         {
    6598           node *n2 = n->car;
    6599 
    6600           while (n2) {
    6601             dump_prefix(n2, offset+2);
    6602             printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
    6603             mrb_parser_dump(mrb, n2->car->cdr, 0);
    6604             n2 = n2->cdr;
    6605           }
    6606         }
    6607       }
    6608       n = n->cdr;
    6609       if (n->car) {
    6610         dump_prefix(n, offset+1);
    6611         printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
    6612       }
    6613       n = n->cdr;
    6614       if (n->car) {
    6615         dump_prefix(n, offset+1);
    6616         printf("post mandatory args:\n");
    6617         dump_recur(mrb, n->car, offset+2);
    6618       }
    6619       n = n->cdr;
    6620       if (n) {
    6621         dump_prefix(n, offset+1);
    6622         printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
    6623       }
     7239      dump_args(mrb, tree->car, offset+1);
    66247240    }
    66257241    tree = tree->cdr;
     
    66377253    break;
    66387254
     7255  case NODE_ARGS_TAIL:
     7256    printf("NODE_ARGS_TAIL:\n");
     7257    {
     7258      node *kws = tree->car;
     7259
     7260      while (kws) {
     7261        mrb_parser_dump(mrb, kws->car, offset+1);
     7262        kws = kws->cdr;
     7263      }
     7264    }
     7265    tree = tree->cdr;
     7266    if (tree->car) {
     7267      mrb_assert(intn(tree->car->car) == NODE_KW_REST_ARGS);
     7268      mrb_parser_dump(mrb, tree->car, offset+1);
     7269    }
     7270    tree = tree->cdr;
     7271    if (tree->car) {
     7272      dump_prefix(tree, offset+1);
     7273      printf("block='%s'\n", mrb_sym_name(mrb, sym(tree->car)));
     7274    }
     7275    break;
     7276
     7277  case NODE_KW_ARG:
     7278    printf("NODE_KW_ARG %s:\n", mrb_sym_name(mrb, sym(tree->car)));
     7279    mrb_parser_dump(mrb, tree->cdr->car, offset + 1);
     7280    break;
     7281
     7282  case NODE_KW_REST_ARGS:
     7283    printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree)));
     7284    break;
     7285
    66397286  default:
    66407287    printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype);
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/mrbgem.rake

    r331 r439  
    2424    end
    2525  end
    26   file objfile("#{current_build_dir}/core/y.tab") => lex_def
    2726
    2827  # Parser
    29   file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t|
     28  file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y", lex_def] do |t|
     29    mkdir_p File.dirname t.name
    3030    yacc.run t.name, t.prerequisites.first
    3131  end
     
    3636  end
    3737
    38   file libfile("#{build.build_dir}/lib/libmruby_core") => core_objs
     38  file build.libmruby_core_static => core_objs
    3939  build.libmruby << core_objs
    4040end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-ext/mrblib/enum.rb

    r331 r439  
    1414
    1515  def drop(n)
    16     raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
     16    n = n.__to_int
    1717    raise ArgumentError, "attempt to drop negative size" if n < 0
    1818
    19     n = n.to_int
    2019    ary = []
    2120    self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 }
     
    5857
    5958  def take(n)
    60     raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
    61     i = n.to_int
     59    n = n.__to_int
     60    i = n.to_i
    6261    raise ArgumentError, "attempt to take negative size" if i < 0
    6362    ary = []
     
    114113
    115114  def each_cons(n, &block)
    116     raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
     115    n = n.__to_int
    117116    raise ArgumentError, "invalid size" if n <= 0
    118117
    119118    return to_enum(:each_cons,n) unless block
    120119    ary = []
    121     n = n.to_int
     120    n = n.to_i
    122121    self.each do |*val|
    123122      ary.shift if ary.size == n
     
    142141
    143142  def each_slice(n, &block)
    144     raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
     143    n = n.__to_int
    145144    raise ArgumentError, "invalid slice size" if n <= 0
    146145
    147146    return to_enum(:each_slice,n) unless block
    148147    ary = []
    149     n = n.to_int
     148    n = n.to_i
    150149    self.each do |*val|
    151150      ary << val.__svalue
     
    202201    }
    203202    if ary.size > 1
    204       __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1) do |a,b|
    205         a <=> b
    206       end
     203      ary.sort!
    207204    end
    208205    ary.collect{|e,i| orig[i]}
    209206  end
    210207
    211   NONE = Object.new
    212208  ##
    213209  # call-seq:
     
    226222      return nil
    227223    when 1
    228       n = args[0]
    229       raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
    230       i = n.to_int
     224      i = args[0].__to_int
    231225      raise ArgumentError, "attempt to take negative size" if i < 0
    232226      ary = []
     
    452446  #  call-seq:
    453447  #     enum.none? [{ |obj| block }]   -> true or false
     448  #     enum.none?(pattern)            -> true or false
    454449  #
    455450  #  Passes each element of the collection to the given block. The method
     
    458453  #  <code>true</code> only if none of the collection members is true.
    459454  #
     455  #  If a pattern is supplied instead, the method returns whether
     456  #  <code>pattern === element</code> for none of the collection members.
     457  #
    460458  #     %w(ant bear cat).none? { |word| word.length == 5 } #=> true
    461459  #     %w(ant bear cat).none? { |word| word.length >= 4 } #=> false
     460  #     %w{ant bear cat}.none?(/d/)                        #=> true
     461  #     [1, 3.14, 42].none?(Float)                         #=> false
    462462  #     [].none?                                           #=> true
    463463  #     [nil, false].none?                                 #=> true
    464464  #     [nil, true].none?                                  #=> false
    465465
    466   def none?(&block)
    467     if block
     466  def none?(pat=NONE, &block)
     467    if pat != NONE
     468      self.each do |*val|
     469        return false if pat === val.__svalue
     470      end
     471    elsif block
    468472      self.each do |*val|
    469473        return false if block.call(*val)
     
    480484  #  call-seq:
    481485  #    enum.one? [{ |obj| block }]   -> true or false
     486  #    enum.one?(pattern)            -> true or false
    482487  #
    483488  # Passes each element of the collection to the given block. The method
     
    487492  # true.
    488493  #
     494  # If a pattern is supplied instead, the method returns whether
     495  # <code>pattern === element</code> for exactly one collection member.
     496  #
    489497  #    %w(ant bear cat).one? { |word| word.length == 4 }  #=> true
    490498  #    %w(ant bear cat).one? { |word| word.length > 4 }   #=> false
    491499  #    %w(ant bear cat).one? { |word| word.length < 4 }   #=> false
     500  #    %w{ant bear cat}.one?(/t/)                         #=> false
    492501  #    [nil, true, 99].one?                               #=> false
    493502  #    [nil, true, false].one?                            #=> true
    494   #
    495 
    496   def one?(&block)
     503  #    [ nil, true, 99 ].one?(Integer)                    #=> true
     504  #    [].one?                                            #=> false
     505
     506  def one?(pat=NONE, &block)
    497507    count = 0
    498     if block
     508    if pat!=NONE
     509      self.each do |*val|
     510        count += 1 if pat === val.__svalue
     511        return false if count > 1
     512      end
     513    elsif block
    499514      self.each do |*val|
    500515        count += 1 if block.call(*val)
     
    511526  end
    512527
     528  # ISO 15.3.2.2.1
     529  #  call-seq:
     530  #     enum.all? [{ |obj| block } ]   -> true or false
     531  #     enum.all?(pattern)             -> true or false
     532  #
     533  #  Passes each element of the collection to the given block. The method
     534  #  returns <code>true</code> if the block never returns
     535  #  <code>false</code> or <code>nil</code>. If the block is not given,
     536  #  Ruby adds an implicit block of <code>{ |obj| obj }</code> which will
     537  #  cause #all? to return +true+ when none of the collection members are
     538  #  +false+ or +nil+.
     539  #
     540  #  If a pattern is supplied instead, the method returns whether
     541  #  <code>pattern === element</code> for every collection member.
     542  #
     543  #     %w[ant bear cat].all? { |word| word.length >= 3 } #=> true
     544  #     %w[ant bear cat].all? { |word| word.length >= 4 } #=> false
     545  #     %w[ant bear cat].all?(/t/)                        #=> false
     546  #     [1, 2i, 3.14].all?(Numeric)                       #=> true
     547  #     [nil, true, 99].all?                              #=> false
     548  #
     549  def all?(pat=NONE, &block)
     550    if pat != NONE
     551      self.each{|*val| return false unless pat === val.__svalue}
     552    elsif block
     553      self.each{|*val| return false unless block.call(*val)}
     554    else
     555      self.each{|*val| return false unless val.__svalue}
     556    end
     557    true
     558  end
     559
     560  # ISO 15.3.2.2.2
     561  #  call-seq:
     562  #     enum.any? [{ |obj| block }]   -> true or false
     563  #     enum.any?(pattern)            -> true or false
     564  #
     565  #  Passes each element of the collection to the given block. The method
     566  #  returns <code>true</code> if the block ever returns a value other
     567  #  than <code>false</code> or <code>nil</code>. If the block is not
     568  #  given, Ruby adds an implicit block of <code>{ |obj| obj }</code> that
     569  #  will cause #any? to return +true+ if at least one of the collection
     570  #  members is not +false+ or +nil+.
     571  #
     572  #  If a pattern is supplied instead, the method returns whether
     573  #  <code>pattern === element</code> for any collection member.
     574  #
     575  #     %w[ant bear cat].any? { |word| word.length >= 3 } #=> true
     576  #     %w[ant bear cat].any? { |word| word.length >= 4 } #=> true
     577  #     %w[ant bear cat].any?(/d/)                        #=> false
     578  #     [nil, true, 99].any?(Integer)                     #=> true
     579  #     [nil, true, 99].any?                              #=> true
     580  #     [].any?                                           #=> false
     581  #
     582  def any?(pat=NONE, &block)
     583    if pat != NONE
     584      self.each{|*val| return true if pat === val.__svalue}
     585    elsif block
     586      self.each{|*val| return true if block.call(*val)}
     587    else
     588      self.each{|*val| return true if val.__svalue}
     589    end
     590    false
     591  end
     592
    513593  ##
    514594  #  call-seq:
     
    525605  #
    526606
    527   def each_with_object(obj=nil, &block)
    528     raise ArgumentError, "wrong number of arguments (0 for 1)" if obj.nil?
    529 
     607  def each_with_object(obj, &block)
    530608    return to_enum(:each_with_object, obj) unless block
    531609
     
    592670      n = -1
    593671    else
    594       unless nv.respond_to?(:to_int)
    595         raise TypeError, "no implicit conversion of #{nv.class} into Integer"
    596       end
    597       n = nv.to_int
    598       unless n.kind_of?(Integer)
    599         raise TypeError, "no implicit conversion of #{nv.class} into Integer"
    600       end
     672      n = nv.__to_int
    601673      return nil if n <= 0
    602674    end
     
    657729  #  call-seq:
    658730  #     enum.zip(arg, ...)                  -> an_array_of_array
     731  #     enum.zip(arg, ...) { |arr| block }  -> nil
    659732  #
    660733  #  Takes one element from <i>enum</i> and merges corresponding
     
    663736  #  count of arguments.  The length of the resulting sequence will be
    664737  #  <code>enum#size</code>.  If the size of any argument is less than
    665   #  <code>enum#size</code>, <code>nil</code> values are supplied.
    666   #
    667 
    668   def zip(*arg)
    669     ary = []
    670     arg = arg.map{|a|a.to_a}
     738  #  <code>enum#size</code>, <code>nil</code> values are supplied. If
     739  #  a block is given, it is invoked for each output array, otherwise
     740  #  an array of arrays is returned.
     741  #
     742  #     a = [ 4, 5, 6 ]
     743  #     b = [ 7, 8, 9 ]
     744  #
     745  #     a.zip(b)                 #=> [[4, 7], [5, 8], [6, 9]]
     746  #     [1, 2, 3].zip(a, b)      #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
     747  #     [1, 2].zip(a, b)         #=> [[1, 4, 7], [2, 5, 8]]
     748  #     a.zip([1, 2], [8])       #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
     749  #
     750  #     c = []
     751  #     a.zip(b) { |x, y| c << x + y }  #=> nil
     752  #     c                               #=> [11, 13, 15]
     753  #
     754
     755  def zip(*arg, &block)
     756    result = block ? nil : []
     757    arg = arg.map do |a|
     758      unless a.respond_to?(:to_a)
     759        raise TypeError, "wrong argument type #{a.class} (must respond to :to_a)"
     760      end
     761      a.to_a
     762    end
     763
    671764    i = 0
    672765    self.each do |*val|
     
    678771        idx += 1
    679772      end
    680       ary.push(a)
    681773      i += 1
    682     end
    683     ary
     774      if result.nil?
     775        block.call(a)
     776      else
     777        result.push(a)
     778      end
     779    end
     780    result
    684781  end
    685782
     
    695792  #
    696793
    697   def to_h
     794  def to_h(&blk)
    698795    h = {}
    699     self.each do |*v|
    700       v = v.__svalue
    701       raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array
    702       raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2
    703       h[v[0]] = v[1]
     796    if blk
     797      self.each do |v|
     798        v = blk.call(v)
     799        raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array
     800        raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2
     801        h[v[0]] = v[1]
     802      end
     803    else
     804      self.each do |*v|
     805        v = v.__svalue
     806        raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array
     807        raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2
     808        h[v[0]] = v[1]
     809      end
    704810    end
    705811    h
    706812  end
    707813
    708   def nil.to_h
    709     {}
     814  def uniq(&block)
     815    hash = {}
     816    if block
     817      self.each do|*v|
     818        v = v.__svalue
     819        hash[block.call(v)] ||= v
     820      end
     821    else
     822      self.each do|*v|
     823        v = v.__svalue
     824        hash[v] ||= v
     825      end
     826    end
     827    hash.values
     828  end
     829
     830  def filter_map(&blk)
     831    return to_enum(:filter_map) unless blk
     832
     833    ary = []
     834    self.each do |x|
     835      x = blk.call(x)
     836      ary.push x if x
     837    end
     838    ary
     839  end
     840
     841  alias filter select
     842
     843  ##
     844  # call-seq:
     845  #   enum.tally -> a_hash
     846  #
     847  # Tallys the collection.  Returns a hash where the keys are the
     848  # elements and the values are numbers of elements in the collection
     849  # that correspond to the key.
     850  #
     851  #    ["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
     852  def tally
     853    hash = {}
     854    self.each do |x|
     855      hash[x] = (hash[x]||0)+1
     856    end
     857    hash
    710858  end
    711859end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-ext/test/enum.rb

    r331 r439  
    101101  assert_true %w(ant bear cat).none? { |word| word.length == 5 }
    102102  assert_false %w(ant bear cat).none? { |word| word.length >= 4 }
     103  assert_false [1, 3.14, 42].none?(Float)
    103104  assert_true [].none?
    104105  assert_true [nil, false].none?
     
    110111  assert_false %w(ant bear cat).one? { |word| word.length > 4 }
    111112  assert_false %w(ant bear cat).one? { |word| word.length < 4 }
     113  assert_true [1, 3.14, 42].one?(Float)
    112114  assert_false [nil, true, 99].one?
    113115  assert_true [nil, true, false].one?
     116  assert_true [ nil, true, 99 ].one?(Integer)
     117  assert_false [].one?
     118end
     119
     120assert("Enumerable#all? (enhancement)") do
     121  assert_false [1, 2, 3.14].all?(Integer)
     122  assert_true [1, 2, 3.14].all?(Numeric)
     123end
     124
     125assert("Enumerable#any? (enhancement)") do
     126  assert_false [1, 2, 3].all?(Float)
     127  assert_true [nil, true, 99].any?(Integer)
    114128end
    115129
    116130assert("Enumerable#each_with_object") do
    117   assert_true [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], (1..10).each_with_object([]) { |i, a| a << i*2 }
     131  assert_equal [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], (1..10).each_with_object([]) { |i, a| a << i*2 }
    118132  assert_raise(ArgumentError) { (1..10).each_with_object() { |i, a| a << i*2 } }
    119133end
     
    122136  r = (1..3)
    123137  a = []
    124   assert_equal (1..3), r.reverse_each { |v| a << v }
     138  assert_same r, r.reverse_each { |v| a << v }
    125139  assert_equal [3, 2, 1], a
    126140end
     
    153167  assert_equal [[1, 4, 7], [2, 5, 8]], [1, 2].zip(a, b)
    154168  assert_equal [[4, 1, 8], [5, 2, nil], [6, nil, nil]], a.zip([1, 2], [8])
     169
     170  ret = []
     171  assert_equal nil, a.zip([1, 2], [8]) { |i| ret << i }
     172  assert_equal [[4, 1, 8], [5, 2, nil], [6, nil, nil]], ret
     173
     174  assert_raise(TypeError) { [1].zip(1) }
    155175end
    156176
     
    167187  assert_equal Hash, h.class
    168188  assert_equal h0, h
    169   # mruby-enum-ext also provides nil.to_h
    170   assert_equal Hash.new, nil.to_h
     189  assert_equal({1=>4,3=>8}, c.new.to_h{|k,v|[k,v*2]})
    171190end
     191
     192assert("Enumerable#filter_map") do
     193  assert_equal [4, 8, 12, 16, 20], (1..10).filter_map{|i| i * 2 if i%2==0}
     194end
     195
     196assert("Enumerable#tally") do
     197  assert_equal({"a"=>1, "b"=>2, "c"=>1}, ["a", "b", "c", "b"].tally)
     198end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-lazy/mrblib/lazy.rb

    r331 r439  
    4444
    4545    def to_enum(meth=:each, *args, &block)
     46      unless self.respond_to?(meth)
     47        raise ArgumentError, "undefined method #{meth}"
     48      end
    4649      lz = Lazy.new(self, &block)
    4750      lz.obj = self
     
    7073    def reject(&block)
    7174      Lazy.new(self){|yielder, val|
    72         if not block.call(val)
     75        unless block.call(val)
    7376          yielder << val
    7477        end
     
    156159    end
    157160
     161    def uniq(&block)
     162      hash = {}
     163      Lazy.new(self){|yielder, val|
     164        if block
     165          v = block.call(val)
     166        else
     167          v = val
     168        end
     169        unless hash.include?(v)
     170          yielder << val
     171          hash[v] = val
     172        end
     173      }
     174    end
     175
    158176    alias force to_a
    159177  end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-lazy/test/lazy.rb

    r331 r439  
    4141end
    4242
    43 assert("Enumrator::Lazy#to_enum") do
     43assert("Enumerator::Lazy#to_enum") do
    4444  lazy_enum = (0..Float::INFINITY).lazy.to_enum(:each_slice, 2)
    4545  assert_kind_of Enumerator::Lazy, lazy_enum
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enumerator/mrbgem.rake

    r321 r439  
    33  spec.author  = 'mruby developers'
    44  spec.add_dependency('mruby-fiber', :core => 'mruby-fiber')
    5   spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext'
    65  spec.summary = 'Enumerator class'
    76end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enumerator/mrblib/enumerator.rb

    r331 r439  
    9090
    9191  ##
    92   # @overload initialize(size = nil, &block)
    9392  # @overload initialize(obj, method = :each, *args)
    9493  #
     
    110109  #     p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
    111110  #
    112   def initialize(obj=nil, meth=:each, *args, &block)
    113     if block_given?
     111  # In the second, deprecated, form, a generated Enumerator iterates over the
     112  # given object using the given method with the given arguments passed. This
     113  # form is left only for internal use.
     114  #
     115  # Use of this form is discouraged.  Use Kernel#enum_for or Kernel#to_enum
     116  # instead.
     117  def initialize(obj=NONE, meth=:each, *args, &block)
     118    if block
    114119      obj = Generator.new(&block)
    115     else
    116       raise ArgumentError unless obj
     120    elsif obj == NONE
     121      raise ArgumentError, "wrong number of arguments (given 0, expected 1+)"
    117122    end
    118123
    119124    @obj = obj
    120125    @meth = meth
    121     @args = args.dup
     126    @args = args
    122127    @fib = nil
    123128    @dst = nil
     
    126131    @stop_exc = false
    127132  end
    128   attr_accessor :obj, :meth, :args, :fib
    129   private :obj, :meth, :args, :fib
     133  attr_accessor :obj, :meth, :args
     134  attr_reader :fib
    130135
    131136  def initialize_copy(obj)
     
    152157  # +offset+:: the starting index to use
    153158  #
    154   def with_index(offset=0)
    155     return to_enum :with_index, offset unless block_given?
    156     offset = if offset.nil?
    157       0
    158     elsif offset.respond_to?(:to_int)
    159       offset.to_int
     159  def with_index(offset=0, &block)
     160    return to_enum :with_index, offset unless block
     161
     162    if offset.nil?
     163      offset = 0
    160164    else
    161       raise TypeError, "no implicit conversion of #{offset.class} into Integer"
     165      offset = offset.__to_int
    162166    end
    163167
     
    165169    enumerator_block_call do |*i|
    166170      n += 1
    167       yield i.__svalue, n
     171      block.call i.__svalue, n
    168172    end
    169173  end
     
    210214  #   # => foo:2
    211215  #
    212   def with_object(object)
    213     return to_enum(:with_object, object) unless block_given?
     216  def with_object(object, &block)
     217    return to_enum(:with_object, object) unless block
    214218
    215219    enumerator_block_call do |i|
    216       yield [i,object]
     220      block.call [i,object]
    217221    end
    218222    object
     
    220224
    221225  def inspect
    222     return "#<#{self.class}: uninitialized>" unless @obj
    223 
    224226    if @args && @args.size > 0
    225227      args = @args.join(", ")
    226       "#<#{self.class}: #{@obj}:#{@meth}(#{args})>"
     228      "#<#{self.class}: #{@obj.inspect}:#{@meth}(#{args})>"
    227229    else
    228       "#<#{self.class}: #{@obj}:#{@meth}>"
     230      "#<#{self.class}: #{@obj.inspect}:#{@meth}>"
    229231    end
    230232  end
     
    242244  # === Examples
    243245  #
    244   #   "Hello, world!".scan(/\w+/)                     #=> ["Hello", "world"]
    245   #   "Hello, world!".to_enum(:scan, /\w+/).to_a      #=> ["Hello", "world"]
    246   #   "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"]
     246  #   Array.new(3)                     #=> [nil, nil, nil]
     247  #   Array.new(3) { |i| i }           #=> [0, 1, 2]
     248  #   Array.to_enum(:new, 3).to_a      #=> [0, 1, 2]
     249  #   Array.to_enum(:new).each(3).to_a #=> [0, 1, 2]
    247250  #
    248251  #   obj = Object.new
     
    278281      obj.args = args
    279282    end
    280     return obj unless block_given?
     283    return obj unless block
    281284    enumerator_block_call(&block)
    282285  end
     
    539542  class Yielder
    540543    def initialize(&block)
    541       raise LocalJumpError, "no block given" unless block_given?
     544      raise LocalJumpError, "no block given" unless block
    542545
    543546      @proc = block
     
    553556    end
    554557  end
     558
     559  ##
     560  # call-seq:
     561  #    Enumerator.produce(initial = nil) { |val| } -> enumerator
     562  #
     563  # Creates an infinite enumerator from any block, just called over and
     564  # over.  Result of the previous iteration is passed to the next one.
     565  # If +initial+ is provided, it is passed to the first iteration, and
     566  # becomes the first element of the enumerator; if it is not provided,
     567  # first iteration receives +nil+, and its result becomes first
     568  # element of the iterator.
     569  #
     570  # Raising StopIteration from the block stops an iteration.
     571  #
     572  # Examples of usage:
     573  #
     574  #   Enumerator.produce(1, &:succ)   # => enumerator of 1, 2, 3, 4, ....
     575  #
     576  #   Enumerator.produce { rand(10) } # => infinite random number sequence
     577  #
     578  #   ancestors = Enumerator.produce(node) { |prev| node = prev.parent or raise StopIteration }
     579  #   enclosing_section = ancestors.find { |n| n.type == :section }
     580  def Enumerator.produce(init=NONE, &block)
     581    raise ArgumentError, "no block given" if block.nil?
     582    Enumerator.new do |y|
     583      if init == NONE
     584        val = nil
     585      else
     586        val = init
     587        y.yield(val)
     588      end
     589      begin
     590        while true
     591          y.yield(val = block.call(val))
     592        end
     593      rescue StopIteration
     594        # do nothing
     595      end
     596    end
     597  end
    555598end
    556599
     
    560603  #   obj.to_enum(method = :each, *args)                 -> enum
    561604  #   obj.enum_for(method = :each, *args)                -> enum
    562   #   obj.to_enum(method = :each, *args) {|*args| block} -> enum
    563   #   obj.enum_for(method = :each, *args){|*args| block} -> enum
    564605  #
    565606  # Creates a new Enumerator which will enumerate by calling +method+ on
    566607  # +obj+, passing +args+ if any.
    567   #
    568   # If a block is given, it will be used to calculate the size of
    569   # the enumerator without the need to iterate it (see Enumerator#size).
    570608  #
    571609  # === Examples
     
    586624  # a generic Enumerable, in case no block is passed.
    587625  #
    588   # Here is such an example, with parameter passing and a sizing block:
     626  # Here is such an example with parameter passing:
    589627  #
    590628  #     module Enumerable
     
    593631  #         raise ArgumentError, "#{n} is negative!" if n < 0
    594632  #         unless block_given?
    595   #           return to_enum(__method__, n) do # __method__ is :repeat here
    596   #             sz = size     # Call size and multiply by n...
    597   #             sz * n if sz  # but return nil if size itself is nil
    598   #           end
     633  #           return to_enum(__method__, n) # __method__ is :repeat here
    599634  #         end
    600635  #         each do |*val|
     
    613648    Enumerator.new self, meth, *args
    614649  end
    615   alias :enum_for :to_enum
     650  alias enum_for to_enum
    616651end
    617652
    618653module Enumerable
    619654  # use Enumerator to use infinite sequence
    620   def zip(*arg)
    621     ary = []
    622     arg = arg.map{|a|a.each}
    623     i = 0
    624     self.each do |*val|
    625       a = []
    626       a.push(val.__svalue)
    627       idx = 0
    628       while idx < arg.size
    629         begin
    630           a.push(arg[idx].next)
    631         rescue StopIteration
    632           a.push(nil)
     655  def zip(*args, &block)
     656    args = args.map do |a|
     657      if a.respond_to?(:each)
     658        a.to_enum(:each)
     659      else
     660        raise TypeError, "wrong argument type #{a.class} (must respond to :each)"
     661      end
     662    end
     663
     664    result = block ? nil : []
     665
     666    each do |*val|
     667      tmp = [val.__svalue]
     668      args.each do |arg|
     669        v = if arg.nil?
     670          nil
     671        else
     672          begin
     673            arg.next
     674          rescue StopIteration
     675            nil
     676          end
    633677        end
    634         idx += 1
     678        tmp.push(v)
    635679      end
    636       ary.push(a)
    637       i += 1
    638     end
    639     ary
     680      if result.nil?
     681        block.call(tmp)
     682      else
     683        result.push(tmp)
     684      end
     685    end
     686
     687    result
    640688  end
    641689end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enumerator/test/enumerator.rb

    r331 r439  
    77end
    88
    9 assert 'Enumerator' do
     9def assert_take(exp, enumerator)
     10  result = []
     11  n = exp.size
     12  enumerator.each do |v|
     13    result << v
     14    n -= 1
     15    break if n == 0
     16  end if n > 0
     17  assert_equal exp, result
     18end
     19
     20assert 'Enumerator.class' do
    1021  assert_equal Class, Enumerator.class
    1122end
    1223
    13 assert 'Enumerator' do
     24assert 'Enumerator.superclass' do
    1425  assert_equal Object, Enumerator.superclass
    1526end
     
    2031  assert_equal [[:x,1],[:y,2]], {x:1, y:2}.each.map{|i| i}.sort
    2132  assert_equal [1,2,3], @obj.to_enum(:foo, 1,2,3).to_a
    22   assert_equal [1,2,3], Enumerator.new(@obj, :foo, 1,2,3).to_a
    23   assert_equal [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3)
     33  assert_take [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }
    2434  assert_raise(ArgumentError) { Enumerator.new }
    25   enum = @obj.to_enum
    26   assert_raise(NoMethodError) { enum.each {} }
    2735
    2836  # examples
     
    3442    end
    3543  end
    36   assert_equal fib.take(10), [1,1,2,3,5,8,13,21,34,55]
     44  assert_take [1,1,2,3,5,8,13,21,34,55], fib
    3745end
    3846
     
    5462  @obj.to_enum(:foo, 1, 2, 3).with_index(10).with_index(20) { |*i| a << i }
    5563  assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a
    56 end
    57 
    58 assert 'Enumerator#with_index nonnum offset' do
    59   s = Object.new
    60   def s.to_int; 1 end
    61   assert_equal([[1,1],[2,2],[3,3]], @obj.to_enum(:foo, 1, 2, 3).with_index(s).to_a)
    6264end
    6365
     
    100102assert 'Enumerator#inspect' do
    101103  e = (0..10).each
    102   assert_equal("#<Enumerator: 0..10:each>", e.inspect)
    103   e = Enumerator.new("FooObject", :foo, 1)
    104   assert_equal("#<Enumerator: FooObject:foo(1)>", e.inspect)
    105   e = Enumerator.new("FooObject", :foo, 1, 2, 3)
    106   assert_equal("#<Enumerator: FooObject:foo(1, 2, 3)>", e.inspect)
     104  assert_equal('#<Enumerator: 0..10:each>', e.inspect)
     105  e = 'FooObject'.enum_for(:foo, 1)
     106  assert_equal('#<Enumerator: "FooObject":foo(1)>', e.inspect)
     107  e = 'FooObject'.enum_for(:foo, 1, 2, 3)
     108  assert_equal('#<Enumerator: "FooObject":foo(1, 2, 3)>', e.inspect)
     109  e = nil.enum_for(:to_s)
     110  assert_equal('#<Enumerator: nil:to_s>', e.inspect)
    107111end
    108112
     
    426430
    427431assert 'Kernel#to_enum' do
     432  e = nil
    428433  assert_equal Enumerator, [].to_enum.class
    429   assert_raise(ArgumentError){ nil.to_enum }
     434  assert_nothing_raised { e = [].to_enum(:_not_implemented_) }
     435  assert_raise(NoMethodError) { e.first }
    430436end
    431437
     
    510516assert 'Hash#select' do
    511517  h = {1=>2,3=>4,5=>6}
    512   hret = h.select.with_index {|a,b| a[1] == 4}
     518  hret = h.select.with_index {|a,_b| a[1] == 4}
    513519  assert_equal({3=>4}, hret)
    514520  assert_equal({1=>2,3=>4,5=>6}, h)
     
    517523assert 'Hash#select!' do
    518524  h = {1=>2,3=>4,5=>6}
    519   hret = h.select!.with_index {|a,b| a[1] == 4}
     525  hret = h.select!.with_index {|a,_b| a[1] == 4}
    520526  assert_equal h, hret
    521527  assert_equal({3=>4}, h)
     
    524530assert 'Hash#reject' do
    525531  h = {1=>2,3=>4,5=>6}
    526   hret = h.reject.with_index {|a,b| a[1] == 4}
     532  hret = h.reject.with_index {|a,_b| a[1] == 4}
    527533  assert_equal({1=>2,5=>6}, hret)
    528534  assert_equal({1=>2,3=>4,5=>6}, h)
     
    531537assert 'Hash#reject!' do
    532538  h = {1=>2,3=>4,5=>6}
    533   hret = h.reject!.with_index {|a,b| a[1] == 4}
     539  hret = h.reject!.with_index {|a,_b| a[1] == 4}
    534540  assert_equal h, hret
    535541  assert_equal({1=>2,5=>6}, h)
     
    545551  assert_equal [1,2,3,4,5], c
    546552end
     553
     554assert 'Enumerable#zip' do
     555  assert_equal [[1, 10], [2, 11], [3, 12]], [1,2,3].zip(10..Float::INFINITY)
     556
     557  ret = []
     558  assert_equal nil, [1,2,3].zip(10..Float::INFINITY) { |i| ret << i }
     559  assert_equal [[1, 10], [2, 11], [3, 12]], ret
     560
     561  assert_raise(TypeError) { [1].zip(1) }
     562end
     563
     564assert 'Enumerator.produce' do
     565  assert_raise(ArgumentError) { Enumerator.produce }
     566
     567  # Without initial object
     568  passed_args = []
     569  enum = Enumerator.produce {|obj| passed_args << obj; (obj || 0).succ }
     570  assert_equal Enumerator, enum.class
     571  assert_take [1, 2, 3], enum
     572  assert_equal [nil, 1, 2], passed_args
     573
     574  # With initial object
     575  passed_args = []
     576  enum = Enumerator.produce(1) {|obj| passed_args << obj; obj.succ }
     577  assert_take [1, 2, 3], enum
     578  assert_equal [1, 2], passed_args
     579
     580  # Raising StopIteration
     581  words = %w[The quick brown fox jumps over the lazy dog]
     582  enum = Enumerator.produce { words.shift or raise StopIteration }
     583  assert_equal %w[The quick brown fox jumps over the lazy dog], enum.to_a
     584
     585  # Raising StopIteration
     586  object = [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"]
     587  enum = Enumerator.produce(object) {|obj|
     588    obj.respond_to?(:first) or raise StopIteration
     589    obj.first
     590  }
     591  assert_nothing_raised {
     592    assert_equal [
     593      [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"],
     594      [[["abc", "def"], "ghi", "jkl"], "mno", "pqr"],
     595      [["abc", "def"], "ghi", "jkl"],
     596      ["abc", "def"],
     597      "abc",
     598    ], enum.to_a
     599  }
     600end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-error/src/exception.c

    r331 r439  
    99  struct mrb_jmpbuf c_jmp;
    1010  mrb_value result = mrb_nil_value();
     11  int ai = mrb_gc_arena_save(mrb);
    1112
    1213  if (state) { *state = FALSE; }
     
    2324  } MRB_END_EXC(&c_jmp);
    2425
     26  mrb_gc_arena_restore(mrb, ai);
    2527  mrb_gc_protect(mrb, result);
    2628  return result;
     
    3335  struct mrb_jmpbuf c_jmp;
    3436  mrb_value result;
     37  int ai = mrb_gc_arena_save(mrb);
    3538
    3639  MRB_TRY(&c_jmp) {
     
    4043  } MRB_CATCH(&c_jmp) {
    4144    mrb->jmp = prev_jmp;
     45    mrb_gc_arena_restore(mrb, ai);
    4246    ensure(mrb, e_data);
    4347    MRB_THROW(mrb->jmp); /* rethrow catched exceptions */
    4448  } MRB_END_EXC(&c_jmp);
    4549
     50  mrb_gc_arena_restore(mrb, ai);
     51  mrb_gc_protect(mrb, result);
    4652  ensure(mrb, e_data);
     53  mrb_gc_arena_restore(mrb, ai);
    4754  mrb_gc_protect(mrb, result);
    4855  return result;
     
    6572  mrb_bool error_matched = FALSE;
    6673  mrb_int i;
     74  int ai = mrb_gc_arena_save(mrb);
    6775
    6876  MRB_TRY(&c_jmp) {
     
    8391
    8492    mrb->exc = NULL;
     93    mrb_gc_arena_restore(mrb, ai);
    8594    result = rescue(mrb, r_data);
    8695  } MRB_END_EXC(&c_jmp);
    8796
     97  mrb_gc_arena_restore(mrb, ai);
    8898  mrb_gc_protect(mrb, result);
    8999  return result;
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-eval/src/eval.c

    r331 r439  
    1313get_closure_irep(mrb_state *mrb, int level)
    1414{
    15   struct mrb_context *c = mrb->c;
    16   struct REnv *e = c->ci[-1].proc->env;
    17   struct RProc *proc;
    18 
    19   if (level == 0) {
    20     proc = c->ci[-1].proc;
    21     if (MRB_PROC_CFUNC_P(proc)) {
    22       return NULL;
    23     }
    24     return proc->body.irep;
    25   }
    26 
    27   while (--level) {
    28     e = (struct REnv*)e->c;
    29     if (!e) return NULL;
    30   }
    31 
    32   if (!e) return NULL;
    33   if (!MRB_ENV_STACK_SHARED_P(e)) return NULL;
    34   c = e->cxt.c;
    35   proc = c->cibase[e->cioff].proc;
    36 
    37   if (!proc || MRB_PROC_CFUNC_P(proc)) {
     15  struct RProc *proc = mrb->c->ci[-1].proc;
     16
     17  while (level--) {
     18    if (!proc) return NULL;
     19    proc = proc->upper;
     20  }
     21  if (!proc) return NULL;
     22  if (MRB_PROC_CFUNC_P(proc)) {
    3823    return NULL;
    3924  }
     
    4126}
    4227
    43 static inline mrb_code
     28/* search for irep lev above the bottom */
     29static mrb_irep*
     30search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom)
     31{
     32  int i;
     33
     34  for (i=0; i<top->rlen; i++) {
     35    mrb_irep* tmp = top->reps[i];
     36
     37    if (tmp == bottom) return top;
     38    tmp = search_irep(tmp, bnest-1, lev, bottom);
     39    if (tmp) {
     40      if (bnest == lev) return top;
     41      return tmp;
     42    }
     43  }
     44  return NULL;
     45}
     46
     47static uint16_t
    4448search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
    4549{
     
    4953
    5054  for (level = 0; (virep = get_closure_irep(mrb, level)); level++) {
    51     if (!virep || virep->lv == NULL) {
     55    if (virep->lv == NULL) {
    5256      continue;
    5357    }
    5458    for (pos = 0; pos < virep->nlocals - 1; pos++) {
    5559      if (vsym == virep->lv[pos].name) {
    56         return (MKARG_B(pos + 1) | MKARG_C(level + bnest));
    57       }
    58     }
    59   }
    60 
     60        return (pos+1)<<8 | (level+bnest);
     61      }
     62    }
     63  }
     64
     65  return 0;
     66}
     67
     68static int
     69irep_argc(mrb_irep *irep)
     70{
     71  mrb_code c;
     72
     73  c = irep->iseq[0];
     74  if (c == OP_ENTER) {
     75    mrb_aspec ax = PEEK_W(irep->iseq+1);
     76    /* extra 1 means a slot for block */
     77    return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
     78  }
    6179  return 0;
    6280}
     
    7189}
    7290
     91extern uint8_t mrb_insn_size[];
     92extern uint8_t mrb_insn_size1[];
     93extern uint8_t mrb_insn_size2[];
     94extern uint8_t mrb_insn_size3[];
     95
    7396static void
    74 patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest)
    75 {
    76   size_t i;
    77   mrb_code c;
    78   int argc = 0;
    79 
    80   for (i = 0; i < irep->ilen; i++) {
    81     c = irep->iseq[i];
    82     switch(GET_OPCODE(c)){
    83     case OP_ENTER:
    84       {
    85         mrb_aspec ax = GETARG_Ax(c);
    86         /* extra 1 means a slot for block */
    87         argc = MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
    88       }
    89       break;
    90 
     97patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top)
     98{
     99  int i;
     100  uint32_t a;
     101  uint16_t b;
     102  uint8_t c;
     103  mrb_code insn;
     104  int argc = irep_argc(irep);
     105  mrb_code *iseq = (mrb_code *)irep->iseq;
     106
     107  mrb_assert((irep->flags & MRB_ISEQ_NO_FREE) == 0);
     108
     109  for (i = 0; i < irep->ilen; ) {
     110    insn = iseq[i];
     111    switch(insn){
    91112    case OP_EPUSH:
    92       patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1);
     113      a = PEEK_B(iseq+i+1);
     114      patch_irep(mrb, irep->reps[a], bnest + 1, top);
    93115      break;
    94116
    95117    case OP_LAMBDA:
    96       {
    97         int arg_c = GETARG_c(c);
    98         if (arg_c & OP_L_CAPTURE) {
    99           patch_irep(mrb, irep->reps[GETARG_b(c)], bnest + 1);
    100         }
    101       }
     118    case OP_BLOCK:
     119      a = PEEK_B(iseq+i+1);
     120      b = PEEK_B(iseq+i+2);
     121      patch_irep(mrb, irep->reps[b], bnest + 1, top);
    102122      break;
    103123
    104124    case OP_SEND:
    105       if (GETARG_C(c) != 0) {
     125      b = PEEK_B(iseq+i+2);
     126      c = PEEK_B(iseq+i+3);
     127      if (c != 0) {
    106128        break;
    107129      }
    108       {
    109         mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest);
     130      else {
     131        uint16_t arg = search_variable(mrb, irep->syms[b], bnest);
    110132        if (arg != 0) {
    111133          /* must replace */
    112           irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
     134          iseq[i] = OP_GETUPVAR;
     135          iseq[i+2] = arg >> 8;
     136          iseq[i+3] = arg & 0xff;
    113137        }
    114138      }
     
    116140
    117141    case OP_MOVE:
     142      a = PEEK_B(iseq+i+1);
     143      b = PEEK_B(iseq+i+2);
    118144      /* src part */
    119       if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) {
    120         mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest);
     145      if (potential_upvar_p(irep->lv, b, argc, irep->nlocals)) {
     146        uint16_t arg = search_variable(mrb, irep->lv[b - 1].name, bnest);
    121147        if (arg != 0) {
    122148          /* must replace */
    123           irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
     149          iseq[i] = insn = OP_GETUPVAR;
     150          iseq[i+2] = arg >> 8;
     151          iseq[i+3] = arg & 0xff;
    124152        }
    125153      }
    126154      /* dst part */
    127       if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) {
    128         mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest);
     155      if (potential_upvar_p(irep->lv, a, argc, irep->nlocals)) {
     156        uint16_t arg = search_variable(mrb, irep->lv[a - 1].name, bnest);
    129157        if (arg != 0) {
    130158          /* must replace */
    131           irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg;
    132         }
    133       }
    134       break;
    135 
    136     case OP_STOP:
    137       if (mrb->c->ci->acc >= 0) {
    138         irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL);
    139       }
    140       break;
    141     }
     159          iseq[i] = insn = OP_SETUPVAR;
     160          iseq[i+1] = (mrb_code)b;
     161          iseq[i+2] = arg >> 8;
     162          iseq[i+3] = arg & 0xff;
     163        }
     164      }
     165      break;
     166
     167    case OP_GETUPVAR:
     168      a = PEEK_B(iseq+i+1);
     169      b = PEEK_B(iseq+i+2);
     170      c = PEEK_B(iseq+i+3);
     171      {
     172        int lev = c+1;
     173        mrb_irep *tmp = search_irep(top, bnest, lev, irep);
     174        if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
     175          uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
     176          if (arg != 0) {
     177            /* must replace */
     178            iseq[i] = OP_GETUPVAR;
     179            iseq[i+2] = arg >> 8;
     180            iseq[i+3] = arg & 0xff;
     181          }
     182        }
     183      }
     184      break;
     185
     186    case OP_SETUPVAR:
     187      a = PEEK_B(iseq+i+1);
     188      b = PEEK_B(iseq+i+2);
     189      c = PEEK_B(iseq+i+3);
     190      {
     191        int lev = c+1;
     192        mrb_irep *tmp = search_irep(top, bnest, lev, irep);
     193        if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
     194          uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
     195          if (arg != 0) {
     196            /* must replace */
     197            iseq[i] = OP_SETUPVAR;
     198            iseq[i+1] = a;
     199            iseq[i+2] = arg >> 8;
     200            iseq[i+3] = arg & 0xff;
     201          }
     202        }
     203      }
     204      break;
     205
     206    case OP_EXT1:
     207      insn = PEEK_B(iseq+i+1);
     208      i += mrb_insn_size1[insn]+1;
     209      continue;
     210    case OP_EXT2:
     211      insn = PEEK_B(iseq+i+1);
     212      i += mrb_insn_size2[insn]+1;
     213      continue;
     214    case OP_EXT3:
     215      insn = PEEK_B(iseq+i+1);
     216      i += mrb_insn_size3[insn]+1;
     217      continue;
     218    }
     219    i+=mrb_insn_size[insn];
    142220  }
    143221}
     
    146224
    147225static struct RProc*
    148 create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line)
     226create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line)
    149227{
    150228  mrbc_context *cxt;
     
    152230  struct RProc *proc;
    153231  struct REnv *e;
    154   struct mrb_context *c = mrb->c;
     232  mrb_callinfo *ci; /* callinfo of eval caller */
     233  struct RClass *target_class = NULL;
     234  int bidx;
    155235
    156236  if (!mrb_nil_p(binding)) {
     
    159239
    160240  cxt = mrbc_context_new(mrb);
    161   cxt->lineno = line;
     241  cxt->lineno = (uint16_t)line;
    162242
    163243  mrbc_filename(mrb, cxt, file ? file : "(eval)");
    164244  cxt->capture_errors = TRUE;
    165245  cxt->no_optimize = TRUE;
     246  cxt->on_eval = TRUE;
    166247
    167248  p = mrb_parse_nstring(mrb, s, len, cxt);
     
    177258
    178259    if (file) {
    179       str = mrb_format(mrb, " file %S line %S: %S",
    180                        mrb_str_new_cstr(mrb, file),
    181                        mrb_fixnum_value(p->error_buffer[0].lineno),
    182                        mrb_str_new_cstr(mrb, p->error_buffer[0].message));
     260      str = mrb_format(mrb, "file %s line %d: %s",
     261                       file,
     262                       p->error_buffer[0].lineno,
     263                       p->error_buffer[0].message);
    183264    }
    184265    else {
    185       str = mrb_format(mrb, " line %S: %S",
    186                        mrb_fixnum_value(p->error_buffer[0].lineno),
    187                        mrb_str_new_cstr(mrb, p->error_buffer[0].message));
     266      str = mrb_format(mrb, "line %d: %s",
     267                       p->error_buffer[0].lineno,
     268                       p->error_buffer[0].message);
    188269    }
    189270    mrb_parser_free(p);
     
    199280    mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
    200281  }
    201   if (c->ci[-1].proc->target_class) {
    202     proc->target_class = c->ci[-1].proc->target_class;
    203   }
    204   e = c->ci[-1].proc->env;
    205   if (!e) e = c->ci[-1].env;
    206   e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)e);
    207   e->cxt.c = c;
    208   e->cioff = c->ci - c->cibase;
    209   e->stack = c->ci->stackent;
    210   MRB_SET_ENV_STACK_LEN(e, c->ci->proc->body.irep->nlocals);
    211   c->ci->target_class = proc->target_class;
    212   c->ci->env = 0;
    213   proc->env = e;
    214   patch_irep(mrb, proc->body.irep, 0);
     282  if (mrb->c->ci > mrb->c->cibase) {
     283    ci = &mrb->c->ci[-1];
     284  }
     285  else {
     286    ci = mrb->c->cibase;
     287  }
     288  if (ci->proc) {
     289    target_class = MRB_PROC_TARGET_CLASS(ci->proc);
     290  }
     291  if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
     292    if (ci->env) {
     293      e = ci->env;
     294    }
     295    else {
     296      e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV,
     297                                      (struct RClass*)target_class);
     298      e->mid = ci->mid;
     299      e->stack = ci[1].stackent;
     300      e->cxt = mrb->c;
     301      MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals);
     302      bidx = ci->argc;
     303      if (ci->argc < 0) bidx = 2;
     304      else bidx += 1;
     305      MRB_ENV_SET_BIDX(e, bidx);
     306      ci->env = e;
     307    }
     308    proc->e.env = e;
     309    proc->flags |= MRB_PROC_ENVSET;
     310    mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e);
     311  }
     312  proc->upper = ci->proc;
     313  mrb->c->ci->target_class = target_class;
     314  patch_irep(mrb, proc->body.irep, 0, proc->body.irep);
     315  /* mrb_codedump_all(mrb, proc); */
    215316
    216317  mrb_parser_free(p);
     
    223324exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
    224325{
     326  /* no argument passed from eval() */
     327  mrb->c->ci->argc = 0;
    225328  if (mrb->c->ci->acc < 0) {
    226     mrb_value ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0);
     329    ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase;
     330    mrb_value ret = mrb_top_run(mrb, proc, self, 0);
    227331    if (mrb->exc) {
    228332      mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
    229333    }
     334    mrb->c->ci = mrb->c->cibase + cioff;
    230335    return ret;
    231336  }
     337  /* clear block */
     338  mrb->c->stack[1] = mrb_nil_value();
    232339  return mrb_exec_irep(mrb, self, proc);
    233340}
     
    256363  mrb_int argc; mrb_value *argv;
    257364
    258   mrb_get_args(mrb, "*&", &argv, &argc, &b);
     365  mrb_get_args(mrb, "*!&", &argv, &argc, &b);
    259366
    260367  if (mrb_nil_p(b)) {
     
    269376    cv = mrb_singleton_class(mrb, self);
    270377    proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
    271     proc->target_class = mrb_class_ptr(cv);
    272     mrb->c->ci->env = NULL;
     378    MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv));
    273379    mrb_assert(!MRB_PROC_CFUNC_P(proc));
     380    mrb->c->ci->target_class = mrb_class_ptr(cv);
    274381    return exec_irep(mrb, self, proc);
    275382  }
     
    284391{
    285392  mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
    286   mrb_define_method(mrb, mrb->kernel_module, "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));
     393  mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
    287394}
    288395
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-eval/test/eval.rb

    r331 r439  
    3535  assert_equal(2) {
    3636    a = 10
    37     Kernel.eval 'def f(a); b=a.send(:+, 1); end'
     37    Kernel.eval 'def f(a); b=a+1; end'
    3838    f(1)
    3939  }
     
    5959assert('String instance_eval') do
    6060  obj = Object.new
    61   obj.instance_variable_set :@test, 'test'
     61  obj.instance_eval{ @test = 'test' }
    6262  assert_raise(ArgumentError) { obj.instance_eval(0) { } }
    6363  assert_raise(ArgumentError) { obj.instance_eval('0', 'test', 0, 'test') }
     
    8181end
    8282
    83 assert('Object#instance_eval with begin-rescue-ensure execution order') do
     83assert('BasicObject#instance_eval with begin-rescue-ensure execution order') do
    8484  class HellRaiser
    8585    def raise_hell
     
    100100  assert_equal([:enter_raise_hell, :begin, :rescue, :ensure], hell_raiser.raise_hell)
    101101end
     102
     103assert('BasicObject#instance_eval to define singleton methods Issue #3141') do
     104  foo_class = Class.new do
     105    def bar(x)
     106      instance_eval "def baz; #{x}; end"
     107    end
     108  end
     109
     110  f1 = foo_class.new
     111  f2 = foo_class.new
     112  f1.bar 1
     113  f2.bar 2
     114  assert_equal(1){f1.baz}
     115  assert_equal(2){f2.baz}
     116end
     117
     118assert('Kernel.#eval(string) Issue #4021') do
     119  assert_equal('FOO') { (eval <<'EOS').call }
     120foo = "FOO"
     121Proc.new { foo }
     122EOS
     123  assert_equal('FOO') {
     124    def do_eval(code)
     125      eval(code)
     126    end
     127    do_eval(<<'EOS').call
     128foo = "FOO"
     129Proc.new { foo }
     130EOS
     131  }
     132end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-exit/src/mruby-exit.c

    r331 r439  
    55f_exit(mrb_state *mrb, mrb_value self)
    66{
    7   mrb_int i = EXIT_SUCCESS;
     7  mrb_value status = mrb_true_value();
     8  int istatus;
    89
    9   mrb_get_args(mrb, "|i", &i);
    10   exit(i);
     10  mrb_get_args(mrb, "|o", &status);
     11  istatus = mrb_true_p(status) ? EXIT_SUCCESS :
     12            mrb_false_p(status) ? EXIT_FAILURE :
     13            (int)mrb_int(mrb, status);
     14  exit(istatus);
     15
    1116  /* not reached */
    12   return mrb_nil_value();
     17  return status;
    1318}
    1419
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-fiber/src/fiber.c

    r331 r439  
    7373  size_t slen;
    7474
    75   mrb_get_args(mrb, "&", &blk);
     75  mrb_get_args(mrb, "&!", &blk);
    7676
    7777  if (f->cxt) {
    7878    mrb_raise(mrb, E_RUNTIME_ERROR, "cannot initialize twice");
    79   }
    80   if (mrb_nil_p(blk)) {
    81     mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");
    8279  }
    8380  p = mrb_proc_ptr(blk);
     
    124121  /* adjust return callinfo */
    125122  ci = c->ci;
    126   ci->target_class = p->target_class;
     123  ci->target_class = MRB_PROC_TARGET_CLASS(p);
    127124  ci->proc = p;
     125  mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p);
    128126  ci->pc = p->body.irep->iseq;
    129   ci->nregs = p->body.irep->nregs;
    130127  ci[1] = ci[0];
    131128  c->ci++;                      /* push dummy callinfo */
     
    187184  struct mrb_context *c = fiber_check(mrb, self);
    188185  struct mrb_context *old_c = mrb->c;
     186  enum mrb_fiber_state status;
    189187  mrb_value value;
    190188
    191189  fiber_check_cfunc(mrb, c);
    192   if (resume && c->status == MRB_FIBER_TRANSFERRED) {
    193     mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
    194   }
    195   if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMED) {
    196     mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)");
    197   }
    198   if (c->status == MRB_FIBER_TERMINATED) {
     190  status = c->status;
     191  switch (status) {
     192  case MRB_FIBER_TRANSFERRED:
     193    if (resume) {
     194      mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
     195    }
     196    break;
     197  case MRB_FIBER_RUNNING:
     198  case MRB_FIBER_RESUMED:
     199    mrb_raise(mrb, E_FIBER_ERROR, "double resume");
     200    break;
     201  case MRB_FIBER_TERMINATED:
    199202    mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber");
    200   }
    201   mrb->c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED;
     203    break;
     204  default:
     205    break;
     206  }
     207  old_c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED;
    202208  c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c);
    203   if (c->status == MRB_FIBER_CREATED) {
     209  fiber_switch_context(mrb, c);
     210  if (status == MRB_FIBER_CREATED) {
    204211    mrb_value *b, *e;
    205212
    206     if (len >= c->stend - c->stack) {
    207       mrb_raise(mrb, E_FIBER_ERROR, "too many arguments to fiber");
     213    if (!c->ci->proc) {
     214      mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)");
    208215    }
     216    mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */
    209217    b = c->stack+1;
    210218    e = b + len;
     
    212220      *b++ = *a++;
    213221    }
    214     c->cibase->argc = len;
    215     value = c->stack[0] = c->ci->proc->env->stack[0];
     222    c->cibase->argc = (int)len;
     223    value = c->stack[0] = MRB_PROC_ENV(c->ci->proc)->stack[0];
    216224  }
    217225  else {
    218226    value = fiber_result(mrb, a, len);
    219227  }
    220   fiber_switch_context(mrb, c);
    221228
    222229  if (vmexec) {
     
    253260  mrb_bool vmexec = FALSE;
    254261
    255   mrb_get_args(mrb, "*", &a, &len);
     262  mrb_get_args(mrb, "*!", &a, &len);
    256263  if (mrb->c->ci->acc < 0) {
    257264    vmexec = TRUE;
     
    274281 *  execution of the fiber block this method will always return false.
    275282 */
    276 static mrb_value
    277 fiber_alive_p(mrb_state *mrb, mrb_value self)
     283MRB_API mrb_value
     284mrb_fiber_alive_p(mrb_state *mrb, mrb_value self)
    278285{
    279286  struct mrb_context *c = fiber_check(mrb, self);
    280287  return mrb_bool_value(c->status != MRB_FIBER_TERMINATED);
    281288}
     289#define fiber_alive_p mrb_fiber_alive_p
    282290
    283291static mrb_value
     
    287295  mrb_get_args(mrb, "o", &other);
    288296
    289   if (mrb_type(other) != MRB_TT_FIBER) {
     297  if (!mrb_fiber_p(other)) {
    290298    return mrb_false_value();
    291299  }
     
    313321
    314322  fiber_check_cfunc(mrb, mrb->c);
    315   mrb_get_args(mrb, "*", &a, &len);
     323  mrb_get_args(mrb, "*!", &a, &len);
    316324
    317325  if (c == mrb->root_c) {
     
    371379  mrb_int len;
    372380
    373   mrb_get_args(mrb, "*", &a, &len);
     381  mrb_get_args(mrb, "*!", &a, &len);
    374382  return mrb_fiber_yield(mrb, len, a);
    375383}
     
    402410  MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER);
    403411
    404   mrb_define_method(mrb, c, "initialize", fiber_init,    MRB_ARGS_NONE());
     412  mrb_define_method(mrb, c, "initialize", fiber_init,    MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
    405413  mrb_define_method(mrb, c, "resume",     fiber_resume,  MRB_ARGS_ANY());
    406414  mrb_define_method(mrb, c, "transfer",   fiber_transfer, MRB_ARGS_ANY());
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-fiber/test/fiber.rb

    r321 r439  
    7777
    7878assert('Fiber with splat in the block argument list') {
    79   Fiber.new{|*x|x}.resume(1) == [1]
     79  assert_equal([1], Fiber.new{|*x|x}.resume(1))
    8080}
    8181
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/mrbgem.rake

    r321 r439  
    33  spec.author  = 'mruby developers'
    44  spec.summary = 'Hash class extension'
    5   spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext'
    6   spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext'
     5  spec.add_dependency 'mruby-array-ext', core: 'mruby-array-ext'
    76end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/mrblib/hash.rb

    r331 r439  
    2828    if length == 1
    2929      o = object[0]
    30       if o.respond_to?(:to_hash)
     30      if Hash === o
    3131        h = self.new
    32         object[0].to_hash.each { |k, v| h[k] = v }
     32        o.each { |k, v| h[k] = v }
    3333        return h
    3434      elsif o.respond_to?(:to_a)
     
    6363  ##
    6464  # call-seq:
    65   #     Hash.try_convert(obj) -> hash or nil
    66   #
    67   # Try to convert <i>obj</i> into a hash, using to_hash method.
    68   # Returns converted hash or nil if <i>obj</i> cannot be converted
    69   # for any reason.
    70   #
    71   #     Hash.try_convert({1=>2})   # => {1=>2}
    72   #     Hash.try_convert("1=>2")   # => nil
    73   #
    74   def self.try_convert(obj)
    75     if obj.respond_to?(:to_hash)
    76       obj.to_hash
    77     else
    78       nil
    79     end
    80   end
    81 
    82   ##
    83   # call-seq:
    8465  #     hsh.merge!(other_hash)                                 -> hsh
    8566  #     hsh.merge!(other_hash){|key, oldval, newval| block}    -> hsh
     
    10283
    10384  def merge!(other, &block)
    104     raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash)
     85    raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
    10586    if block
    10687      other.each_key{|k|
     
    11495
    11596  alias update merge!
     97
     98  ##
     99  # call-seq:
     100  #   hsh.compact!    -> hsh
     101  #
     102  # Removes all nil values from the hash. Returns the hash.
     103  # Returns nil if the hash does not contain nil values.
     104  #
     105  #   h = { a: 1, b: false, c: nil }
     106  #   h.compact!     #=> { a: 1, b: false }
     107  #
     108
     109  def compact!
     110    keys = self.keys
     111    nk = keys.select{|k|
     112      self[k] != nil
     113    }
     114    return nil if (keys.size == nk.size)
     115    h = {}
     116    nk.each {|k|
     117      h[k] = self[k]
     118    }
     119    h
     120    self.replace(h)
     121  end
     122
     123  ##
     124  # call-seq:
     125  #    hsh.compact     -> new_hsh
     126  #
     127  # Returns a new hash with the nil values/key pairs removed
     128  #
     129  #    h = { a: 1, b: false, c: nil }
     130  #    h.compact     #=> { a: 1, b: false }
     131  #    h             #=> { a: 1, b: false, c: nil }
     132  #
     133  def compact
     134    h = {}
     135    self.keys.select{|k|
     136      self[k] != nil
     137    }.each {|k|
     138      h[k] = self[k]
     139    }
     140    h
     141  end
    116142
    117143  ##
     
    150176        none
    151177      else
    152         raise KeyError, "Key not found: #{key}"
     178        raise KeyError, "Key not found: #{key.inspect}"
    153179      end
    154180    else
     
    172198
    173199  def delete_if(&block)
    174     return to_enum :delete_if unless block_given?
     200    return to_enum :delete_if unless block
    175201
    176202    self.each do |k, v|
     
    229255
    230256  def keep_if(&block)
    231     return to_enum :keep_if unless block_given?
     257    return to_enum :keep_if unless block
    232258
    233259    keys = []
     
    285311  #
    286312  def <(hash)
    287     begin
    288       hash = hash.to_hash
    289     rescue NoMethodError
    290       raise TypeError, "can't convert #{hash.class} to Hash"
    291     end
     313    raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
    292314    size < hash.size and all? {|key, val|
    293315      hash.key?(key) and hash[key] == val
     
    309331  #
    310332  def <=(hash)
    311     begin
    312       hash = hash.to_hash
    313     rescue NoMethodError
    314       raise TypeError, "can't convert #{hash.class} to Hash"
    315     end
     333    raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
    316334    size <= hash.size and all? {|key, val|
    317335      hash.key?(key) and hash[key] == val
     
    333351  #
    334352  def >(hash)
    335     begin
    336       hash = hash.to_hash
    337     rescue NoMethodError
    338       raise TypeError, "can't convert #{hash.class} to Hash"
    339     end
     353    raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
    340354    size > hash.size and hash.all? {|key, val|
    341355      key?(key) and self[key] == val
     
    357371  #
    358372  def >=(hash)
    359     begin
    360       hash = hash.to_hash
    361     rescue NoMethodError
    362       raise TypeError, "can't convert #{hash.class} to Hash"
    363     end
     373    raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
    364374    size >= hash.size and hash.all? {|key, val|
    365375      key?(key) and self[key] == val
     
    383393    end
    384394  end
     395
     396  ##
     397  # call-seq:
     398  #    hsh.transform_keys {|key| block } -> new_hash
     399  #    hsh.transform_keys                -> an_enumerator
     400  #
     401  # Returns a new hash, with the keys computed from running the block
     402  # once for each key in the hash, and the values unchanged.
     403  #
     404  # If no block is given, an enumerator is returned instead.
     405  #
     406  def transform_keys(&block)
     407    return to_enum :transform_keys unless block
     408    hash = {}
     409    self.keys.each do |k|
     410      new_key = block.call(k)
     411      hash[new_key] = self[k]
     412    end
     413    hash
     414  end
     415  ##
     416  # call-seq:
     417  #    hsh.transform_keys! {|key| block } -> hsh
     418  #    hsh.transform_keys!                -> an_enumerator
     419  #
     420  # Invokes the given block once for each key in <i>hsh</i>, replacing it
     421  # with the new key returned by the block, and then returns <i>hsh</i>.
     422  #
     423  # If no block is given, an enumerator is returned instead.
     424  #
     425  def transform_keys!(&block)
     426    return to_enum :transform_keys! unless block
     427    self.keys.each do |k|
     428      value = self[k]
     429      self.__delete(k)
     430      k = block.call(k) if block
     431      self[k] = value
     432    end
     433    self
     434  end
     435  ##
     436  # call-seq:
     437  #    hsh.transform_values {|value| block } -> new_hash
     438  #    hsh.transform_values                  -> an_enumerator
     439  #
     440  # Returns a new hash with the results of running the block once for
     441  # every value.
     442  # This method does not change the keys.
     443  #
     444  # If no block is given, an enumerator is returned instead.
     445  #
     446  def transform_values(&b)
     447    return to_enum :transform_values unless block_given?
     448    hash = {}
     449    self.keys.each do |k|
     450      hash[k] = yield(self[k])
     451    end
     452    hash
     453  end
     454
     455  ##
     456  # call-seq:
     457  #    hsh.transform_values! {|key| block } -> hsh
     458  #    hsh.transform_values!                -> an_enumerator
     459  #
     460  # Invokes the given block once for each value in the hash, replacing
     461  # with the new value returned by the block, and then returns <i>hsh</i>.
     462  #
     463  # If no block is given, an enumerator is returned instead.
     464  #
     465  def transform_values!(&b)
     466    return to_enum :transform_values! unless block_given?
     467    self.keys.each do |k|
     468      self[k] = yield(self[k])
     469    end
     470    self
     471  end
     472
     473  def to_proc
     474    ->x{self[x]}
     475  end
     476
     477  ##
     478  # call-seq:
     479  #   hsh.fetch_values(key, ...)                 -> array
     480  #   hsh.fetch_values(key, ...) { |key| block } -> array
     481  #
     482  # Returns an array containing the values associated with the given keys
     483  # but also raises <code>KeyError</code> when one of keys can't be found.
     484  # Also see <code>Hash#values_at</code> and <code>Hash#fetch</code>.
     485  #
     486  #   h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
     487  #
     488  #   h.fetch_values("cow", "cat")                   #=> ["bovine", "feline"]
     489  #   h.fetch_values("cow", "bird")                  # raises KeyError
     490  #   h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
     491  #
     492  def fetch_values(*keys, &block)
     493    keys.map do |k|
     494      self.fetch(k, &block)
     495    end
     496  end
     497
     498  alias filter select
     499  alias filter! select!
    385500end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/src/hash-ext.c

    r331 r439  
    3737}
    3838
     39/*
     40 *  call-seq:
     41 *     hsh.slice(*keys) -> a_hash
     42 *
     43 *  Returns a hash containing only the given keys and their values.
     44 *
     45 *     h = { a: 100, b: 200, c: 300 }
     46 *     h.slice(:a)           #=> {:a=>100}
     47 *     h.slice(:b, :c, :d)   #=> {:b=>200, :c=>300}
     48 */
     49static mrb_value
     50hash_slice(mrb_state *mrb, mrb_value hash)
     51{
     52  mrb_value *argv, result;
     53  mrb_int argc, i;
     54
     55  mrb_get_args(mrb, "*", &argv, &argc);
     56  result = mrb_hash_new_capa(mrb, argc);
     57  if (argc == 0) return result; /* empty hash */
     58  for (i = 0; i < argc; i++) {
     59    mrb_value key = argv[i];
     60    mrb_value val;
     61
     62    val = mrb_hash_fetch(mrb, hash, key, mrb_undef_value());
     63    if (!mrb_undef_p(val)) {
     64      mrb_hash_set(mrb, result, key, val);
     65    }
     66  }
     67  return result;
     68}
     69
    3970void
    4071mrb_mruby_hash_ext_gem_init(mrb_state *mrb)
     
    4475  h = mrb->hash_class;
    4576  mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY());
     77  mrb_define_method(mrb, h, "slice",     hash_slice, MRB_ARGS_ANY());
    4678}
    4779
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/test/hash.rb

    r331 r439  
    4646end
    4747
    48 assert('Hash.try_convert') do
    49   assert_nil Hash.try_convert(nil)
    50   assert_nil Hash.try_convert("{1=>2}")
    51   assert_equal({1=>2}, Hash.try_convert({1=>2}))
    52 end
    53 
    5448assert('Hash#merge!') do
    5549  a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' }
     
    8175  h = Hash.new { |hash,k| hash[k] = k }
    8276  assert_equal keys, h.values_at(*keys)
     77end
     78
     79assert('Hash#compact') do
     80  h = { "cat" => "feline", "dog" => nil, "cow" => false }
     81
     82  assert_equal({ "cat" => "feline", "cow" => false }, h.compact)
     83  assert_equal({ "cat" => "feline", "dog" => nil, "cow" => false }, h)
     84end
     85
     86assert('Hash#compact!') do
     87  h = { "cat" => "feline", "dog" => nil, "cow" => false }
     88
     89  h.compact!
     90  assert_equal({ "cat" => "feline", "cow" => false }, h)
    8391end
    8492
     
    255263  assert_nil(h.dig(:d))
    256264end
     265
     266assert("Hash#transform_keys") do
     267  h = {"1" => 100, "2" => 200}
     268  assert_equal({"1!" => 100, "2!" => 200},
     269               h.transform_keys{|k| k+"!"})
     270  assert_equal({1 => 100, 2 => 200},
     271               h.transform_keys{|k|k.to_i})
     272  assert_same(h, h.transform_keys!{|k|k.to_i})
     273  assert_equal({1 => 100, 2 => 200}, h)
     274end
     275
     276assert("Hash#transform_values") do
     277  h = {a: 1, b: 2, c: 3}
     278  assert_equal({a: 2, b: 5, c: 10},
     279               h.transform_values{|v| v * v + 1})
     280  assert_equal({a: "1", b: "2", c: "3"},
     281               h.transform_values{|v|v.to_s})
     282  assert_same(h, h.transform_values!{|v|v.to_s})
     283  assert_equal({a: "1", b: "2", c: "3"}, h)
     284end
     285
     286assert("Hash#slice") do
     287  h = { a: 100, b: 200, c: 300 }
     288  assert_equal({:a=>100}, h.slice(:a))
     289  assert_equal({:b=>200, :c=>300}, h.slice(:b, :c, :d))
     290end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-inline-struct/test/inline.c

    r331 r439  
    1212  mrb_get_args(mrb, "o", &object);
    1313
    14   if (mrb_float_p(object))
    15   {
    16     snprintf(string, size, "float(%.3f)", mrb_float(object));
     14  if (mrb_fixnum_p(object)) {
     15    strncpy(string, "fixnum", size-1);
    1716  }
    18   else if (mrb_fixnum_p(object))
    19   {
    20     snprintf(string, size, "fixnum(%" MRB_PRId ")", mrb_fixnum(object));
     17#ifndef MRB_WITHOUT_FLOAT
     18  else if (mrb_float_p(object)) {
     19    strncpy(string, "float", size-1);
    2120  }
    22   else if (mrb_string_p(object))
    23   {
    24     snprintf(string, size, "string(%s)", mrb_string_value_cstr(mrb, &object));
     21#endif
     22  else if (mrb_string_p(object)) {
     23    strncpy(string, "string", size-1);
     24  }
     25  else {
     26    strncpy(string, "anything", size-1);
    2527  }
    2628
     
    4850  if (mrb_obj_class(mrb, object) != mrb_class_get(mrb, "InlineStructTest"))
    4951  {
    50     mrb_raisef(mrb, E_TYPE_ERROR, "Expected InlineStructTest");
     52    mrb_raise(mrb, E_TYPE_ERROR, "Expected InlineStructTest");
    5153  }
    5254  return mrb_bool_value(((char*)mrb_istruct_ptr(object))[0] == 's');
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-inline-struct/test/inline.rb

    r331 r439  
    1818assert('InlineStructTest#dup') do
    1919  obj = InlineStructTest.new(1)
    20   assert_equal obj.to_s, 'fixnum(1)'
    21   assert_equal obj.dup.to_s, 'fixnum(1)'
     20  assert_equal obj.to_s, 'fixnum'
     21  assert_equal obj.dup.to_s, 'fixnum'
    2222end
    2323
    2424assert('InlineStructTest#clone') do
    2525  obj = InlineStructTest.new(1)
    26   assert_equal obj.to_s, 'fixnum(1)'
    27   assert_equal obj.clone.to_s, 'fixnum(1)'
     26  assert_equal obj.to_s, 'fixnum'
     27  assert_equal obj.clone.to_s, 'fixnum'
    2828end
    2929
     
    3939assert('InlineStructTest#mutate (dup)') do
    4040  obj1 = InlineStructTest.new("foo")
    41   assert_equal obj1.to_s, "string(foo)"
     41  assert_equal obj1.to_s, "string"
    4242  obj2 = obj1.dup
    43   assert_equal obj2.to_s, "string(foo)"
     43  assert_equal obj2.to_s, "string"
    4444  obj1.mutate
    45   assert_equal obj1.to_s, "mutate(foo)"
    46   assert_equal obj2.to_s, "string(foo)"
     45  assert_equal obj1.to_s, "mutate"
     46  assert_equal obj2.to_s, "string"
    4747end
    4848
    4949assert('InlineStructTest#mutate (clone)') do
    5050  obj1 = InlineStructTest.new("foo")
    51   assert_equal obj1.to_s, "string(foo)"
     51  assert_equal obj1.to_s, "string"
    5252  obj2 = obj1.clone
    53   assert_equal obj2.to_s, "string(foo)"
     53  assert_equal obj2.to_s, "string"
    5454  obj1.mutate
    55   assert_equal obj1.to_s, "mutate(foo)"
    56   assert_equal obj2.to_s, "string(foo)"
     55  assert_equal obj1.to_s, "mutate"
     56  assert_equal obj2.to_s, "string"
    5757end
    5858
     
    102102    assert_equal InlineStructTest.length, 3 * 8
    103103  end
    104 
    105   assert('InlineStructTest w/float [64 bit]') do
    106     obj = InlineStructTest.new(1.25)
    107     assert_equal obj.to_s, "float(1.250)"
    108   end
    109 
    110   assert('InlineStructTest w/fixnum [64 bit]') do
    111     obj = InlineStructTest.new(42)
    112     assert_equal obj.to_s, "fixnum(42)"
    113   end
    114 
    115   assert('InlineStructTest w/string [64 bit]') do
    116     obj = InlineStructTest.new("hello")
    117     assert_equal obj.to_s, "string(hello)"
    118   end
    119 
    120   assert('InlineStructTest w/long string [64 bit]') do
    121     obj = InlineStructTest.new("this won't fit in 3 * 8 bytes available for the structure")
    122     assert_equal obj.to_s, "string(this won't fit i"
    123   end
    124104end
    125105
     
    129109    assert_equal InlineStructTest.length, 3 * 4
    130110  end
     111end
    131112
    132   assert('InlineStructTest w/float [32 bit]') do
    133     obj = InlineStructTest.new(1.25)
    134     assert_equal obj.to_s, "float(1.250"
    135   end
    136 
    137   assert('InlineStructTest w/fixnum [32 bit]') do
    138     obj = InlineStructTest.new(42)
    139     assert_equal obj.to_s, "fixnum(42)"
    140   end
    141 
    142   assert('InlineStructTest w/string [32 bit]') do
    143     obj = InlineStructTest.new("hello")
    144     assert_equal obj.to_s, "string(hell"
    145   end
    146 
    147   assert('InlineStructTest w/long string [32 bit]') do
    148     obj = InlineStructTest.new("this won't fit in 3 * 4 bytes available for the structure")
    149     assert_equal obj.to_s, "string(this"
     113# 16-bit mode
     114if InlineStructTest.length == 6
     115  assert('InlineStructTest length [16 bit]') do
     116    assert_equal InlineStructTest.length, 3 * 2
    150117  end
    151118end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-kernel-ext/mrbgem.rake

    r321 r439  
    22  spec.license = 'MIT'
    33  spec.author  = 'mruby developers'
    4   spec.summary = 'Kernel module extension'
     4  spec.summary = 'extensional function-like methods'
    55end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-kernel-ext/src/kernel.c

    r331 r439  
    2121      break;
    2222    case 1:
    23       if (mrb_type(v) == MRB_TT_RANGE) {
     23      if (mrb_range_p(v)) {
    2424        mrb_int beg, len;
    25         if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) {
     25        if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == MRB_RANGE_OK) {
    2626          lev = beg;
    2727          n = len;
     
    3232      }
    3333      else {
    34         v = mrb_to_int(mrb, v);
    35         lev = mrb_fixnum(v);
     34        lev = mrb_int(mrb, v);
    3635        if (lev < 0) {
    37           mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
     36          mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v);
    3837        }
    3938        n = bt_len - lev;
     
    4140      break;
    4241    case 2:
    43       lev = mrb_fixnum(mrb_to_int(mrb, v));
    44       n = mrb_fixnum(mrb_to_int(mrb, length));
     42      lev = mrb_int(mrb, v);
     43      n = mrb_int(mrb, length);
    4544      if (lev < 0) {
    46         mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
     45        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v);
    4746      }
    4847      if (n < 0) {
    49         mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length);
     48        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%v)", length);
    5049      }
    5150      break;
     
    9493 *  In any case, strings should be strictly conformed to numeric
    9594 *  representation. This behavior is different from that of
    96  *  <code>String#to_i</code>.  Non string values will be converted using
    97  *  <code>to_int</code>, and <code>to_i</code>. Passing <code>nil</code>
    98  *  raises a TypeError.
     95 *  <code>String#to_i</code>.  Non string values will be treated as integers.
     96 *  Passing <code>nil</code> raises a TypeError.
    9997 *
    10098 *     Integer(123.999)    #=> 123
     
    115113}
    116114
     115#ifndef MRB_WITHOUT_FLOAT
    117116/*
    118117 *  call-seq:
     
    135134  return mrb_Float(mrb, arg);
    136135}
     136#endif
    137137
    138138/*
     
    141141 *
    142142 *  Returns <i>arg</i> as an <code>String</code>.
    143  *
    144  *  First tries to call its <code>to_str</code> method, then its to_s method.
     143 *  converted using <code>to_s</code> method.
    145144 *
    146145 *     String(self)        #=> "main"
     
    154153
    155154  mrb_get_args(mrb, "o", &arg);
    156   tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_str");
    157   if (mrb_nil_p(tmp)) {
    158     tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s");
    159   }
     155  tmp = mrb_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s");
    160156  return tmp;
    161157}
     
    165161 *     Array(arg)    -> array
    166162 *
    167  *  Returns +arg+ as an Array.
    168  *
    169  *  First tries to call Array#to_ary on +arg+, then Array#to_a.
     163 *  Returns +arg+ as an Array using to_a method.
    170164 *
    171165 *     Array(1..5)   #=> [1, 2, 3, 4, 5]
     
    178172
    179173  mrb_get_args(mrb, "o", &arg);
    180   tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_ary");
    181   if (mrb_nil_p(tmp)) {
    182     tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a");
    183   }
     174  tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a");
    184175  if (mrb_nil_p(tmp)) {
    185176    return mrb_ary_new_from_values(mrb, 1, &arg);
     
    193184 *     Hash(arg)    -> hash
    194185 *
    195  *  Converts <i>arg</i> to a <code>Hash</code> by calling
    196  *  <i>arg</i><code>.to_hash</code>. Returns an empty <code>Hash</code> when
    197  *  <i>arg</i> is <tt>nil</tt> or <tt>[]</tt>.
     186 *  Returns a <code>Hash</code> if <i>arg</i> is a <code>Hash</code>.
     187 *  Returns an empty <code>Hash</code> when <i>arg</i> is <tt>nil</tt>
     188 *  or <tt>[]</tt>.
    198189 *
    199190 *      Hash([])          #=> {}
     
    206197mrb_f_hash(mrb_state *mrb, mrb_value self)
    207198{
    208   mrb_value arg, tmp;
    209 
    210   mrb_get_args(mrb, "o", &arg);
    211   if (mrb_nil_p(arg)) {
     199  mrb_value arg;
     200
     201  mrb_get_args(mrb, "o", &arg);
     202  if (mrb_nil_p(arg) || (mrb_array_p(arg) && RARRAY_LEN(arg) == 0)) {
    212203    return mrb_hash_new(mrb);
    213204  }
    214   tmp = mrb_check_convert_type(mrb, arg, MRB_TT_HASH, "Hash", "to_hash");
    215   if (mrb_nil_p(tmp)) {
    216     if (mrb_array_p(arg) && RARRAY_LEN(arg) == 0) {
    217       return mrb_hash_new(mrb);
    218     }
    219     mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into Hash",
    220       mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, arg)));
    221   }
    222   return tmp;
     205  return mrb_ensure_hash_type(mrb, arg);
    223206}
    224207
     
    231214  mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2));
    232215  mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
    233   mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY());
     216  mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ARG(1,1));
     217#ifndef MRB_WITHOUT_FLOAT
    234218  mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1));
     219#endif
    235220  mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
    236221  mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-kernel-ext/test/kernel.rb

    r331 r439  
    5050
    5151assert('Kernel#Integer') do
    52   assert_equal(123, Integer(123.999))
    53   assert_equal(26, Integer("0x1a"))
    54   assert_equal(930, Integer("0930", 10))
    55   assert_equal(7, Integer("111", 2))
    56   assert_equal(0, Integer("0"))
    57   assert_equal(0, Integer("00000"))
     52  assert_operator(26, :eql?, Integer("0x1a"))
     53  assert_operator(930, :eql?, Integer("0930", 10))
     54  assert_operator(7, :eql?, Integer("111", 2))
     55  assert_operator(0, :eql?, Integer("0"))
     56  assert_operator(0, :eql?, Integer("00000"))
     57  assert_operator(123, :eql?, Integer('1_2_3'))
     58  assert_operator(123, :eql?, Integer("\t\r\n\f\v 123 \t\r\n\f\v"))
    5859  assert_raise(TypeError) { Integer(nil) }
     60  assert_raise(ArgumentError) { Integer('a') }
     61  assert_raise(ArgumentError) { Integer('4a5') }
     62  assert_raise(ArgumentError) { Integer('1_2__3') }
     63  assert_raise(ArgumentError) { Integer('68_') }
     64  assert_raise(ArgumentError) { Integer('68_ ') }
     65  assert_raise(ArgumentError) { Integer('_68') }
     66  assert_raise(ArgumentError) { Integer(' _68') }
     67  assert_raise(ArgumentError) { Integer('6 8') }
     68  assert_raise(ArgumentError) { Integer("15\0") }
     69  assert_raise(ArgumentError) { Integer("15.0") }
     70  skip unless Object.const_defined?(:Float)
     71  assert_operator(123, :eql?, Integer(123.999))
    5972end
    6073
    6174assert('Kernel#Float') do
    62   assert_equal(1.0, Float(1))
    63   assert_equal(123.456, Float(123.456))
    64   assert_equal(123.456, Float("123.456"))
     75  skip unless Object.const_defined?(:Float)
     76  assert_operator(1.0, :eql?, Float(1))
     77  assert_operator(123.456, :eql?, Float(123.456))
     78  assert_operator(123.456, :eql?, Float("123.456"))
     79  assert_operator(123.0, :eql?, Float('1_2_3'))
     80  assert_operator(12.34, :eql?, Float('1_2.3_4'))
     81  assert_operator(0.9, :eql?, Float('.9'))
     82  assert_operator(0.9, :eql?, Float(" \t\r\n\f\v.9 \t\r\n\f\v"))
     83  assert_operator(16.0, :eql?, Float("0x10"))
    6584  assert_raise(TypeError) { Float(nil) }
     85  assert_raise(ArgumentError) { Float("1. 5") }
     86  assert_raise(ArgumentError) { Float("1.5a") }
     87  assert_raise(ArgumentError) { Float("1.5\0") }
     88  assert_raise(ArgumentError) { Float('a') }
     89  assert_raise(ArgumentError) { Float('4a5') }
     90  assert_raise(ArgumentError) { Float('1_2__3') }
     91  assert_raise(ArgumentError) { Float('68_') }
     92  assert_raise(ArgumentError) { Float('68._7') }
     93  assert_raise(ArgumentError) { Float('68.7_') }
     94  assert_raise(ArgumentError) { Float('68.7_ ') }
     95  assert_raise(ArgumentError) { Float('_68') }
     96  assert_raise(ArgumentError) { Float(' _68') }
     97  assert_raise(ArgumentError) { Float('1_2.3__4') }
    6698end
    6799
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-math/src/math.c

    r331 r439  
    55*/
    66
     7#ifdef MRB_WITHOUT_FLOAT
     8# error Math conflicts 'MRB_WITHOUT_FLOAT' configuration in your 'build_config.rb'
     9#endif
     10
    711#include <mruby.h>
    812#include <mruby/array.h>
     
    1519  struct RClass *math = mrb_module_get(mrb, "Math");
    1620  struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError");
    17   mrb_value str = mrb_str_new_cstr(mrb, func);
    18   mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %S", str);
     21  mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %s", func);
    1922}
    2023
     
    2326
    2427#include <float.h>
    25 
    26 #define MATH_TOLERANCE 1E-12
    2728
    2829double
     
    123124    sum  += term/(2*j+1);
    124125    ++j;
    125   } while (fabs(term/sum) > MATH_TOLERANCE);
     126    if (sum == 0) break;
     127  } while (fabs(term/sum) > DBL_EPSILON);
    126128  return two_sqrtpi*sum;
    127129}
     
    156158    q1 = q2;
    157159    q2 = b/d;
    158   } while (fabs(q1-q2)/q2 > MATH_TOLERANCE);
     160  } while (fabs(q1-q2)/q2 > DBL_EPSILON);
    159161  return one_sqrtpi*exp(-x*x)*q2;
    160162}
    161163
     164#endif
     165
     166#if defined __FreeBSD__ && !defined __FreeBSD_version
     167#include <osreldate.h> /* for __FreeBSD_version */
    162168#endif
    163169
     
    487493{
    488494  mrb_float x, base;
    489   int argc;
     495  mrb_int argc;
    490496
    491497  argc = mrb_get_args(mrb, "f|f", &x, &base);
     
    658664
    659665  mrb_get_args(mrb, "fi", &x, &i);
    660   x = ldexp(x, i);
     666  x = ldexp(x, (int)i);
    661667
    662668  return mrb_float_value(mrb, x);
     
    737743#else
    738744  mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0)));
    739 #endif
    740 
    741 #ifdef MRB_USE_FLOAT
    742   mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-5));
    743 #else
    744   mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-12));
    745745#endif
    746746
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-math/test/math.rb

    r321 r439  
    22# Math Test
    33
    4 ##
    5 # Performs fuzzy check for equality on methods returning floats
    6 # on the basis of the Math::TOLERANCE constant.
    7 def check_float(a, b)
    8   tolerance = Math::TOLERANCE
    9   a = a.to_f
    10   b = b.to_f
    11   if a.finite? and b.finite?
    12     (a-b).abs < tolerance
    13   else
    14     true
     4def assert_float_and_int(exp_ary, act_ary)
     5  assert('assert_float_and_int') do
     6    flo_exp, int_exp, flo_act, int_act = *exp_ary, *act_ary
     7    assert_float(flo_exp, flo_act)
     8    assert_operator(int_exp, :eql?, int_act)
    159  end
    1610end
    1711
    1812assert('Math.sin 0') do
    19   check_float(Math.sin(0), 0)
     13  assert_float(0, Math.sin(0))
    2014end
    2115
    2216assert('Math.sin PI/2') do
    23   check_float(Math.sin(Math::PI / 2), 1)
     17  assert_float(1, Math.sin(Math::PI / 2))
    2418end
    2519
    2620assert('Math.cos 0') do
    27   check_float(Math.cos(0), 1)
     21  assert_float(1, Math.cos(0))
    2822end
    2923
    3024assert('Math.cos PI/2') do
    31   check_float(Math.cos(Math::PI / 2), 0)
     25  assert_float(0, Math.cos(Math::PI / 2))
    3226end
    3327
    3428assert('Math.tan 0') do
    35   check_float(Math.tan(0), 0)
     29  assert_float(0, Math.tan(0))
    3630end
    3731
    3832assert('Math.tan PI/4') do
    39   check_float(Math.tan(Math::PI / 4), 1)
     33  assert_float(1, Math.tan(Math::PI / 4))
    4034end
    4135
    4236assert('Fundamental trig identities') do
    43   result = true
    4437  N = 13
    4538  N.times do |i|
     
    4942    c  = Math.cos(a)
    5043    t  = Math.tan(a)
    51     result &= check_float(s, Math.cos(ca))
    52     result &= check_float(t, 1 / Math.tan(ca))
    53     result &= check_float(s ** 2 + c ** 2, 1)
    54     result &= check_float(t ** 2 + 1, (1/c) ** 2)
    55     result &= check_float((1/t) ** 2 + 1, (1/s) ** 2)
    56   end
    57   result
     44    assert_float(Math.cos(ca), s)
     45    assert_float(1 / Math.tan(ca), t)
     46    assert_float(1, s ** 2 + c ** 2)
     47    assert_float((1/c) ** 2, t ** 2 + 1)
     48    assert_float((1/s) ** 2, (1/t) ** 2 + 1)
     49  end
    5850end
    5951
    6052assert('Math.erf 0') do
    61   check_float(Math.erf(0), 0)
     53  assert_float(0, Math.erf(0))
    6254end
    6355
    6456assert('Math.exp 0') do
    65   check_float(Math.exp(0), 1.0)
     57  assert_float(1.0, Math.exp(0))
    6658end
    6759
    6860assert('Math.exp 1') do
    69   check_float(Math.exp(1), 2.718281828459045)
     61  assert_float(2.718281828459045, Math.exp(1))
    7062end
    7163
    7264assert('Math.exp 1.5') do
    73   check_float(Math.exp(1.5), 4.4816890703380645)
     65  assert_float(4.4816890703380645, Math.exp(1.5))
    7466end
    7567
    7668assert('Math.log 1') do
    77   check_float(Math.log(1), 0)
     69  assert_float(0, Math.log(1))
    7870end
    7971
    8072assert('Math.log E') do
    81   check_float(Math.log(Math::E), 1.0)
     73  assert_float(1.0, Math.log(Math::E))
    8274end
    8375
    8476assert('Math.log E**3') do
    85   check_float(Math.log(Math::E**3), 3.0)
     77  assert_float(3.0, Math.log(Math::E**3))
    8678end
    8779
    8880assert('Math.log2 1') do
    89   check_float(Math.log2(1), 0.0)
     81  assert_float(0.0, Math.log2(1))
    9082end
    9183
    9284assert('Math.log2 2') do
    93   check_float(Math.log2(2), 1.0)
     85  assert_float(1.0, Math.log2(2))
    9486end
    9587
    9688assert('Math.log10 1') do
    97   check_float(Math.log10(1), 0.0)
     89  assert_float(0.0, Math.log10(1))
    9890end
    9991
    10092assert('Math.log10 10') do
    101   check_float(Math.log10(10), 1.0)
     93  assert_float(1.0, Math.log10(10))
    10294end
    10395
    10496assert('Math.log10 10**100') do
    105   check_float(Math.log10(10**100), 100.0)
     97  assert_float(100.0, Math.log10(10**100))
    10698end
    10799
     
    109101  num = [0.0, 1.0, 2.0, 3.0, 4.0]
    110102  sqr = [0, 1, 4, 9, 16]
    111   result = true
    112103  sqr.each_with_index do |v,i|
    113     result &= check_float(Math.sqrt(v), num[i])
    114   end
    115   result
     104    assert_float(num[i], Math.sqrt(v))
     105  end
    116106end
    117107
     
    119109  num = [-2.0, -1.0, 0.0, 1.0, 2.0]
    120110  cub = [-8, -1, 0, 1, 8]
    121   result = true
    122111  cub.each_with_index do |v,i|
    123     result &= check_float(Math.cbrt(v), num[i])
    124   end
    125   result
     112    assert_float(num[i], Math.cbrt(v))
     113  end
    126114end
    127115
    128116assert('Math.hypot') do
    129   check_float(Math.hypot(3, 4), 5.0)
    130 end
    131 
    132 assert('Math.frexp 1234') do
    133   n = 1234
    134   fraction, exponent = Math.frexp(n)
    135   check_float(Math.ldexp(fraction, exponent), n)
     117  assert_float(5.0, Math.hypot(3, 4))
    136118end
    137119
    138120assert('Math.erf 1') do
    139   check_float(Math.erf(1), 0.842700792949715)
     121  assert_float(0.842700792949715, Math.erf(1))
    140122end
    141123
    142124assert('Math.erfc 1') do
    143   check_float(Math.erfc(1), 0.157299207050285)
     125  assert_float(0.157299207050285, Math.erfc(1))
    144126end
    145127
    146128assert('Math.erf -1') do
    147   check_float(Math.erf(-1), -0.8427007929497148)
     129  assert_float(-0.8427007929497148, Math.erf(-1))
    148130end
    149131
    150132assert('Math.erfc -1') do
    151   check_float(Math.erfc(-1), 1.8427007929497148)
    152 end
     133  assert_float(1.8427007929497148, Math.erfc(-1))
     134end
     135
     136assert('Math.acos') do
     137  assert_float(0 * Math::PI / 4, Math.acos( 1.0))
     138  assert_float(1 * Math::PI / 4, Math.acos( 1.0 / Math.sqrt(2)))
     139  assert_float(2 * Math::PI / 4, Math.acos( 0.0))
     140  assert_float(4 * Math::PI / 4, Math.acos(-1.0))
     141  assert_raise(Math::DomainError) { Math.acos(+1.1) }
     142  assert_raise(Math::DomainError) { Math.acos(-1.1) }
     143end
     144
     145assert('Math.asin') do
     146  assert_float( 0 * Math::PI / 4, Math.asin( 0.0))
     147  assert_float( 1 * Math::PI / 4, Math.asin( 1.0 / Math.sqrt(2)))
     148  assert_float( 2 * Math::PI / 4, Math.asin( 1.0))
     149  assert_float(-2 * Math::PI / 4, Math.asin(-1.0))
     150  assert_raise(Math::DomainError) { Math.asin(+1.1) }
     151  assert_raise(Math::DomainError) { Math.asin(-1.1) }
     152  assert_raise(Math::DomainError) { Math.asin(2.0) }
     153end
     154
     155assert('Math.atan') do
     156  assert_float( 0 * Math::PI / 4, Math.atan( 0.0))
     157  assert_float( 1 * Math::PI / 4, Math.atan( 1.0))
     158  assert_float( 2 * Math::PI / 4, Math.atan(1.0 / 0.0))
     159  assert_float(-1 * Math::PI / 4, Math.atan(-1.0))
     160end
     161
     162assert('Math.cosh') do
     163  assert_float(1, Math.cosh(0))
     164  assert_float((Math::E ** 1 + Math::E ** -1) / 2, Math.cosh(1))
     165  assert_float((Math::E ** 2 + Math::E ** -2) / 2, Math.cosh(2))
     166end
     167
     168assert('Math.sinh') do
     169  assert_float(0, Math.sinh(0))
     170  assert_float((Math::E ** 1 - Math::E ** -1) / 2, Math.sinh(1))
     171  assert_float((Math::E ** 2 - Math::E ** -2) / 2, Math.sinh(2))
     172end
     173
     174assert('Math.tanh') do
     175  assert_float(Math.sinh(0) / Math.cosh(0), Math.tanh(0))
     176  assert_float(Math.sinh(1) / Math.cosh(1), Math.tanh(1))
     177  assert_float(Math.sinh(2) / Math.cosh(2), Math.tanh(2))
     178  assert_float(+1.0, Math.tanh(+1000.0))
     179  assert_float(-1.0, Math.tanh(-1000.0))
     180end
     181
     182assert('Math.acosh') do
     183  assert_float(0, Math.acosh(1))
     184  assert_float(1, Math.acosh((Math::E ** 1 + Math::E ** -1) / 2))
     185  assert_float(2, Math.acosh((Math::E ** 2 + Math::E ** -2) / 2))
     186  assert_raise(Math::DomainError) { Math.acosh(0.9) }
     187  assert_raise(Math::DomainError) { Math.acosh(0) }
     188end
     189
     190assert('Math.asinh') do
     191  assert_float(0, Math.asinh(0))
     192  assert_float(1, Math.asinh((Math::E ** 1 - Math::E ** -1) / 2))
     193  assert_float(2, Math.asinh((Math::E ** 2 - Math::E ** -2) / 2))
     194end
     195
     196assert('Math.atanh') do
     197  assert_float(0, Math.atanh(Math.sinh(0) / Math.cosh(0)))
     198  assert_float(1, Math.atanh(Math.sinh(1) / Math.cosh(1)))
     199  assert_float(2, Math.atanh(Math.sinh(2) / Math.cosh(2)))
     200  assert_float(Float::INFINITY, Math.atanh(1))
     201  assert_float(-Float::INFINITY, Math.atanh(-1))
     202  assert_raise(Math::DomainError) { Math.atanh(+1.1) }
     203  assert_raise(Math::DomainError) { Math.atanh(-1.1) }
     204end
     205
     206assert('Math.atan2') do
     207  assert_float(+0.0, Math.atan2(+0.0, +0.0))
     208  assert_float(-0.0, Math.atan2(-0.0, +0.0))
     209  assert_float(+Math::PI, Math.atan2(+0.0, -0.0))
     210  assert_float(-Math::PI, Math.atan2(-0.0, -0.0))
     211
     212  inf = Float::INFINITY
     213  expected = 3.0 * Math::PI / 4.0
     214  assert_float(+expected, Math.atan2(+inf, -inf))
     215  assert_float(-expected, Math.atan2(-inf, -inf))
     216  expected = Math::PI / 4.0
     217  assert_float(+expected, Math.atan2(+inf, +inf))
     218  assert_float(-expected, Math.atan2(-inf, +inf))
     219
     220  assert_float(0, Math.atan2(0, 1))
     221  assert_float(Math::PI / 4, Math.atan2(1, 1))
     222  assert_float(Math::PI / 2, Math.atan2(1, 0))
     223end
     224
     225assert('Math.ldexp') do
     226  assert_float(0.0, Math.ldexp(0.0, 0.0))
     227  assert_float(0.5, Math.ldexp(0.5, 0.0))
     228  assert_float(1.0, Math.ldexp(0.5, 1.0))
     229  assert_float(2.0, Math.ldexp(0.5, 2.0))
     230  assert_float(3.0, Math.ldexp(0.75, 2.0))
     231end
     232
     233assert('Math.frexp') do
     234  assert_float_and_int([0.0,  0], Math.frexp(0.0))
     235  assert_float_and_int([0.5,  0], Math.frexp(0.5))
     236  assert_float_and_int([0.5,  1], Math.frexp(1.0))
     237  assert_float_and_int([0.5,  2], Math.frexp(2.0))
     238  assert_float_and_int([0.75, 2], Math.frexp(3.0))
     239end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb

    r331 r439  
    1 module Integral
    2   def div(other)
    3     self.divmod(other)[0]
    4   end
    5 
     1class Numeric
    62  def zero?
    73    self == 0
     
    1511    end
    1612  end
     13
     14  def positive?
     15    self > 0
     16  end
     17
     18  def negative?
     19    self < 0
     20  end
    1721end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-numeric-ext/src/numeric_ext.c

    r331 r439  
    11#include <limits.h>
    22#include <mruby.h>
     3#include <mruby/numeric.h>
    34
     5/*
     6 *  call-seq:
     7 *     int.allbits?(mask)  ->  true or false
     8 *
     9 *  Returns +true+ if all bits of <code>+int+ & +mask+</code> are 1.
     10 */
    411static mrb_value
    5 mrb_int_chr(mrb_state *mrb, mrb_value x)
     12mrb_int_allbits(mrb_state *mrb, mrb_value self)
    613{
    7   mrb_int chr;
    8   char c;
     14  mrb_int n, m;
    915
    10   chr = mrb_fixnum(x);
    11   if (chr >= (1 << CHAR_BIT)) {
    12     mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", x);
    13   }
    14   c = (char)chr;
     16  mrb_get_args(mrb, "i", &m);
     17  n = mrb_int(mrb, self);
     18  return mrb_bool_value((n & m) == m);
     19}
    1520
    16   return mrb_str_new(mrb, &c, 1);
     21/*
     22 *  call-seq:
     23 *     int.anybits?(mask)  ->  true or false
     24 *
     25 *  Returns +true+ if any bits of <code>+int+ & +mask+</code> are 1.
     26 */
     27static mrb_value
     28mrb_int_anybits(mrb_state *mrb, mrb_value self)
     29{
     30  mrb_int n, m;
     31
     32  mrb_get_args(mrb, "i", &m);
     33  n = mrb_int(mrb, self);
     34  return mrb_bool_value((n & m) != 0);
     35}
     36
     37/*
     38 *  call-seq:
     39 *     int.nobits?(mask)  ->  true or false
     40 *
     41 *  Returns +true+ if no bits of <code>+int+ & +mask+</code> are 1.
     42 */
     43static mrb_value
     44mrb_int_nobits(mrb_state *mrb, mrb_value self)
     45{
     46  mrb_int n, m;
     47
     48  mrb_get_args(mrb, "i", &m);
     49  n = mrb_int(mrb, self);
     50  return mrb_bool_value((n & m) == 0);
    1751}
    1852
     
    2054mrb_mruby_numeric_ext_gem_init(mrb_state* mrb)
    2155{
    22   struct RClass *i = mrb_class_get(mrb, "Integer");
     56  struct RClass *i = mrb_module_get(mrb, "Integral");
    2357
    24   mrb_define_method(mrb, i, "chr", mrb_int_chr, MRB_ARGS_NONE());
     58  mrb_define_method(mrb, i, "allbits?", mrb_int_allbits, MRB_ARGS_REQ(1));
     59  mrb_define_method(mrb, i, "anybits?", mrb_int_anybits, MRB_ARGS_REQ(1));
     60  mrb_define_method(mrb, i, "nobits?", mrb_int_nobits, MRB_ARGS_REQ(1));
     61
     62#ifndef MRB_WITHOUT_FLOAT
     63  mrb_define_const(mrb, mrb->float_class, "RADIX",        mrb_fixnum_value(MRB_FLT_RADIX));
     64  mrb_define_const(mrb, mrb->float_class, "MANT_DIG",     mrb_fixnum_value(MRB_FLT_MANT_DIG));
     65  mrb_define_const(mrb, mrb->float_class, "EPSILON",      mrb_float_value(mrb, MRB_FLT_EPSILON));
     66  mrb_define_const(mrb, mrb->float_class, "DIG",          mrb_fixnum_value(MRB_FLT_DIG));
     67  mrb_define_const(mrb, mrb->float_class, "MIN_EXP",      mrb_fixnum_value(MRB_FLT_MIN_EXP));
     68  mrb_define_const(mrb, mrb->float_class, "MIN",          mrb_float_value(mrb, MRB_FLT_MIN));
     69  mrb_define_const(mrb, mrb->float_class, "MIN_10_EXP",   mrb_fixnum_value(MRB_FLT_MIN_10_EXP));
     70  mrb_define_const(mrb, mrb->float_class, "MAX_EXP",      mrb_fixnum_value(MRB_FLT_MAX_EXP));
     71  mrb_define_const(mrb, mrb->float_class, "MAX",          mrb_float_value(mrb, MRB_FLT_MAX));
     72  mrb_define_const(mrb, mrb->float_class, "MAX_10_EXP",   mrb_fixnum_value(MRB_FLT_MAX_10_EXP));
     73#endif /* MRB_WITHOUT_FLOAT */
    2574}
    2675
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-numeric-ext/test/numeric.rb

    r331 r439  
    11##
    22# Numeric(Ext) Test
    3 
    4 assert('Integer#chr') do
    5   assert_equal("A", 65.chr)
    6   assert_equal("B", 0x42.chr)
    7 
    8   # multibyte encoding (not support yet)
    9   assert_raise(RangeError) { 256.chr }
    10 end
    113
    124assert('Integer#div') do
     
    157
    168assert('Float#div') do
     9  skip unless Object.const_defined?(:Float)
    1710  assert_float 52, 365.2425.div(7)
    1811end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/mrbgem.rake

    r321 r439  
    22  spec.license = 'MIT'
    33  spec.author  = 'mruby developers'
    4   spec.summary = 'Object class extension'
     4  spec.summary = 'extensional methods shared by all objects'
    55end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/mrblib/object.rb

    r321 r439  
    1 class Object
     1module Kernel
     2  # call-seq:
     3  #   obj.yield_self {|_obj|...} -> an_object
     4  #   obj.then {|_obj|...}       -> an_object
     5  #
     6  # Yields <i>obj</i> and returns the result.
     7  #
     8  #   'my string'.yield_self {|s|s.upcase} #=> "MY STRING"
     9  #
     10  def yield_self(&block)
     11    return to_enum :yield_self unless block
     12    block.call(self)
     13  end
     14  alias then yield_self
     15
    216  ##
    317  #  call-seq:
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/src/object.c

    r331 r439  
    22#include <mruby/array.h>
    33#include <mruby/class.h>
     4#include <mruby/hash.h>
    45#include <mruby/proc.h>
    56
     
    1718}
    1819
     20#ifndef MRB_WITHOUT_FLOAT
    1921/*
    2022 *  call-seq:
     
    2830{
    2931  return mrb_float_value(mrb, 0.0);
     32}
     33#endif
     34
     35/*
     36 *  call-seq:
     37 *     nil.to_h    -> {}
     38 *
     39 *  Always returns an empty hash.
     40 */
     41
     42static mrb_value
     43nil_to_h(mrb_state *mrb, mrb_value obj)
     44{
     45  return mrb_hash_new(mrb);
    3046}
    3147
     
    4157{
    4258  return mrb_fixnum_value(0);
     59}
     60
     61/*
     62 *  call-seq:
     63 *     obj.itself -> an_object
     64 *
     65 *  Returns <i>obj</i>.
     66 *
     67 *      string = 'my string' #=> "my string"
     68 *      string.itself.object_id == string.object_id #=> true
     69 *
     70 */
     71static mrb_value
     72mrb_f_itself(mrb_state *mrb, mrb_value self)
     73{
     74  return self;
    4375}
    4476
     
    68100  mrb_value blk;
    69101  struct RClass *c;
    70   mrb_value args;
    71102
    72   mrb_get_args(mrb, "*&", &argv, &argc, &blk);
    73 
    74   if (mrb_nil_p(blk)) {
    75     mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    76   }
     103  mrb_get_args(mrb, "*&!", &argv, &argc, &blk);
    77104
    78105  switch (mrb_type(self)) {
    79106  case MRB_TT_SYMBOL:
    80107  case MRB_TT_FIXNUM:
     108#ifndef MRB_WITHOUT_FLOAT
    81109  case MRB_TT_FLOAT:
     110#endif
    82111    c = NULL;
    83112    break;
     
    86115    break;
    87116  }
    88   args = mrb_ary_new_from_values(mrb, argc, argv);
    89   argv = RARRAY_PTR(args);
    90117  mrb->c->ci->target_class = c;
    91118  return mrb_yield_cont(mrb, blk, self, argc, argv);
     
    98125
    99126  mrb_define_method(mrb, n, "to_a", nil_to_a,       MRB_ARGS_NONE());
     127#ifndef MRB_WITHOUT_FLOAT
    100128  mrb_define_method(mrb, n, "to_f", nil_to_f,       MRB_ARGS_NONE());
     129#endif
     130  mrb_define_method(mrb, n, "to_h", nil_to_h,       MRB_ARGS_NONE());
    101131  mrb_define_method(mrb, n, "to_i", nil_to_i,       MRB_ARGS_NONE());
    102132
    103   mrb_define_method(mrb, mrb->kernel_module, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
     133  mrb_define_method(mrb, mrb->kernel_module, "itself", mrb_f_itself, MRB_ARGS_NONE());
     134
     135  mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
    104136}
    105137
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/test/nil.rb

    r321 r439  
    44
    55assert('NilClass#to_f') do
     6  skip unless Object.const_defined?(:Float)
    67  assert_equal 0.0, nil.to_f
     8end
     9
     10assert('NilClass#to_h') do
     11  assert_equal Hash.new, nil.to_h
    712end
    813
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-objectspace/src/mruby_objectspace.c

    r331 r439  
    5858  }
    5959
    60   if (!mrb_test(mrb_hash_empty_p(mrb, hash))) {
     60  if (!mrb_hash_empty_p(mrb, hash)) {
    6161    mrb_hash_clear(mrb, hash);
    6262  }
     
    162162  mrb_value cls = mrb_nil_value();
    163163  struct os_each_object_data d;
    164   mrb_get_args(mrb, "&|C", &d.block, &cls);
    165 
    166   if (mrb_nil_p(d.block)) {
    167     mrb_raise(mrb, E_ARGUMENT_ERROR, "Expected block in ObjectSpace.each_object.");
    168   }
     164  mrb_get_args(mrb, "&!|C", &d.block, &cls);
    169165
    170166  d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls);
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-objectspace/test/objectspace.rb

    r321 r439  
    11assert('ObjectSpace.count_objects') do
    22  h = {}
    3   f = Fiber.new {} if Object.const_defined? :Fiber
     3  f = Fiber.new {} if Object.const_defined?(:Fiber)
    44  ObjectSpace.count_objects(h)
    55  assert_kind_of(Hash, h)
     
    3232    objs << {}
    3333  end
     34  ObjectSpace.count_objects(h)
    3435  objs = nil
    35   ObjectSpace.count_objects(h)
    3636  GC.start
    3737  ObjectSpace.count_objects(h_after)
     
    5757
    5858assert 'Check class pointer of ObjectSpace.each_object.' do
    59   ObjectSpace.each_object { |obj| !obj }
     59  assert_nothing_raised { ObjectSpace.each_object { |obj| !obj } }
    6060end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-print/mrblib/print.rb

    r321 r439  
    4646      i += 1
    4747    end
    48     args[0]
     48    args.__svalue
    4949  end
    5050
    51   unless Kernel.respond_to?(:sprintf)
    52     def printf(*args)
    53       raise NotImplementedError.new('printf not available')
    54     end
    55     def sprintf(*args)
    56       raise NotImplementedError.new('sprintf not available')
    57     end
    58   else
    59     def printf(*args)
    60       __printstr__(sprintf(*args))
    61       nil
    62     end
     51  def printf(*args)
     52    __printstr__(sprintf(*args))
     53    nil
    6354  end
    6455end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-print/src/print.c

    r331 r439  
    11#include <mruby.h>
     2
     3#ifdef MRB_DISABLE_STDIO
     4# error print conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
     5#endif
     6
    27#include <mruby/string.h>
    3 #include <stdio.h>
    48#include <string.h>
    59#include <stdlib.h>
     
    2024    if (isatty(fileno(stdout))) {
    2125      DWORD written;
    22       int mlen = RSTRING_LEN(obj);
     26      int mlen = (int)RSTRING_LEN(obj);
    2327      char* utf8 = RSTRING_PTR(obj);
    2428      int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, NULL, 0);
    2529      wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t));
    26       if (utf16 == NULL) return;
    2730      if (MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, utf16, wlen) > 0) {
    2831        utf16[wlen] = 0;
     
    3437#endif
    3538      fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
     39    fflush(stdout);
    3640  }
    3741}
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/mrblib/proc.rb

    r321 r439  
    2828    pproc = self
    2929    make_curry = proc do |given_args=[]|
    30       send(type) do |*args|
     30      __send__(type) do |*args|
    3131        new_args = given_args + args
    3232        if new_args.size >= arity
     
    4040  end
    4141
     42  def <<(other)
     43    ->(*args, &block) { call(other.call(*args, &block)) }
     44  end
     45
     46  def >>(other)
     47    ->(*args, &block) { other.call(call(*args, &block)) }
     48  end
     49
    4250end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/src/proc.c

    r331 r439  
    2626    const char *filename;
    2727
    28     filename = mrb_debug_get_filename(irep, 0);
    29     line = mrb_debug_get_line(irep, 0);
     28    filename = mrb_debug_get_filename(mrb, irep, 0);
     29    line = mrb_debug_get_line(mrb, irep, 0);
    3030
    3131    return (!filename && line == -1)? mrb_nil_value()
     
    3939  struct RProc *p = mrb_proc_ptr(self);
    4040  mrb_value str = mrb_str_new_lit(mrb, "#<Proc:");
    41   mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
     41  mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
    4242
    4343  if (!MRB_PROC_CFUNC_P(p)) {
     
    4747    mrb_str_cat_lit(mrb, str, "@");
    4848
    49     filename = mrb_debug_get_filename(irep, 0);
     49    filename = mrb_debug_get_filename(mrb, irep, 0);
    5050    mrb_str_cat_cstr(mrb, str, filename ? filename : "-");
    5151    mrb_str_cat_lit(mrb, str, ":");
    5252
    53     line = mrb_debug_get_line(irep, 0);
     53    line = mrb_debug_get_line(mrb, irep, 0);
    5454    if (line != -1) {
    55       str = mrb_format(mrb, "%S:%S", str, mrb_fixnum_value(line));
     55      mrb_str_concat(mrb, str, mrb_fixnum_value(line));
    5656    }
    5757    else {
     
    7373  mrb_value blk;
    7474
    75   mrb_get_args(mrb, "&", &blk);
    76   if (mrb_nil_p(blk)) {
    77     mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
    78   }
     75  mrb_get_args(mrb, "&!", &blk);
    7976
    8077  return blk;
     
    9592{
    9693  struct parameters_type {
     94    size_t len;
     95    const char *name;
    9796    int size;
    98     const char *name;
    9997  } *p, parameters_list [] = {
    100     {0, "req"},
    101     {0, "opt"},
    102     {0, "rest"},
    103     {0, "req"},
    104     {0, "block"},
    105     {0, NULL}
     98    {sizeof("req")   - 1, "req",   0},
     99    {sizeof("opt")   - 1, "opt",   0},
     100    {sizeof("rest")  - 1, "rest",  0},
     101    {sizeof("req")   - 1, "req",   0},
     102    {sizeof("block") - 1, "block", 0},
     103    {0, NULL, 0}
    106104  };
    107105  const struct RProc *proc = mrb_proc_ptr(self);
    108106  const struct mrb_irep *irep = proc->body.irep;
    109107  mrb_aspec aspec;
    110   mrb_value sname, parameters;
     108  mrb_value parameters;
    111109  int i, j;
     110  int max = -1;
    112111
    113112  if (MRB_PROC_CFUNC_P(proc)) {
     
    121120    return mrb_ary_new(mrb);
    122121  }
    123   if (GET_OPCODE(*irep->iseq) != OP_ENTER) {
     122  if (*irep->iseq != OP_ENTER) {
    124123    return mrb_ary_new(mrb);
    125124  }
    126125
    127126  if (!MRB_PROC_STRICT_P(proc)) {
     127    parameters_list[0].len = sizeof("opt") - 1;
    128128    parameters_list[0].name = "opt";
     129    parameters_list[3].len = sizeof("opt") - 1;
    129130    parameters_list[3].name = "opt";
    130131  }
    131132
    132   aspec = GETARG_Ax(*irep->iseq);
     133  aspec = PEEK_W(irep->iseq+1);
    133134  parameters_list[0].size = MRB_ASPEC_REQ(aspec);
    134135  parameters_list[1].size = MRB_ASPEC_OPT(aspec);
     
    139140  parameters = mrb_ary_new_capa(mrb, irep->nlocals-1);
    140141
     142  max = irep->nlocals-1;
    141143  for (i = 0, p = parameters_list; p->name; p++) {
    142     if (p->size <= 0) continue;
    143     sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name));
     144    mrb_value sname = mrb_symbol_value(mrb_intern_static(mrb, p->name, p->len));
     145
    144146    for (j = 0; j < p->size; i++, j++) {
    145       mrb_value a = mrb_ary_new(mrb);
     147      mrb_value a;
     148
     149      a = mrb_ary_new(mrb);
    146150      mrb_ary_push(mrb, a, sname);
    147       if (irep->lv[i].name) {
    148         mrb_ary_push(mrb, a, mrb_symbol_value(irep->lv[i].name));
     151      if (i < max && irep->lv[i].name) {
     152        mrb_sym sym = irep->lv[i].name;
     153        const char *name = mrb_sym_name(mrb, sym);
     154        switch (name[0]) {
     155        case '*': case '&':
     156          break;
     157        default:
     158          mrb_ary_push(mrb, a, mrb_symbol_value(sym));
     159          break;
     160        }
    149161      }
    150162      mrb_ary_push(mrb, parameters, a);
     
    164176  mrb_define_method(mrb, p, "parameters",      mrb_proc_parameters,      MRB_ARGS_NONE());
    165177
    166   mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE());
    167   mrb_define_method(mrb, mrb->kernel_module,       "proc", mrb_kernel_proc, MRB_ARGS_NONE());
     178  mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
     179  mrb_define_method(mrb, mrb->kernel_module,       "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
    168180}
    169181
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.c

    r331 r439  
    1414  mrb_sym n;
    1515  mrb_value n_val;
     16  mrb_method_t m;
     17  struct RProc *p;
    1618  mrb_get_args(mrb, "n", &n);
    1719  n_val = mrb_symbol_value(n);
    18   mrb_define_method_raw(mrb, mrb_class_ptr(self), n,
    19                         mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val));
     20  p = mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val);
     21  MRB_METHOD_FROM_PROC(m, p);
     22  mrb_define_method_raw(mrb, mrb_class_ptr(self), n, m);
    2023  return self;
    2124}
     
    3437  mrb_sym n;
    3538  mrb_value *argv; mrb_int argc;
     39  mrb_method_t m;
     40  struct RProc *p;
    3641  mrb_get_args(mrb, "na", &n, &argv, &argc);
    37   mrb_define_method_raw(mrb, mrb_class_ptr(self), n,
    38                         mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv));
     42  p = mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv);
     43  MRB_METHOD_FROM_PROC(m, p);
     44  mrb_define_method_raw(mrb, mrb_class_ptr(self), n, m);
    3945  return self;
    4046}
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.rb

    r331 r439  
    22# Proc(Ext) Test
    33
     4def enable_debug_info?
     5  return @enable_debug_info unless @enable_debug_info == nil
     6  begin
     7    raise
     8  rescue => e
     9    @enable_debug_info = !e.backtrace.empty?
     10  end
     11end
     12
    413assert('Proc#source_location') do
    5   loc = Proc.new {}.source_location
    6   next true if loc.nil?
    7   assert_equal loc[0][-7, 7], 'proc.rb'
    8   assert_equal loc[1], 5
     14  skip unless enable_debug_info?
     15  file, line = Proc.new{}.source_location
     16  assert_equal __FILE__, file
     17  assert_equal __LINE__ - 2, line
    918end
    1019
    1120assert('Proc#inspect') do
    1221  ins = Proc.new{}.inspect
    13   assert_kind_of String, ins
     22  if enable_debug_info?
     23    metas = %w(\\ * ? [ ] { })
     24    file = __FILE__.split("").map{|c| metas.include?(c) ? "\\#{c}" : c}.join
     25    line = __LINE__ - 4
     26  else
     27    file = line = "-"
     28  end
     29  assert_match "#<Proc:0x*@#{file}:#{line}>", ins
     30end
     31
     32assert('Proc#parameters') do
     33  parameters = Proc.new{|x,y=42,*other|}.parameters
     34  assert_equal [[:opt, :x], [:opt, :y], [:rest, :other]], parameters
    1435end
    1536
     
    6788assert('Kernel#proc') do
    6889  assert_true !proc{|a|}.lambda?
     90
     91  assert_raise LocalJumpError do
     92    proc{ break }.call
     93  end
     94end
     95
     96assert "Proc#<< and Proc#>>" do
     97  add3 = ->(n) { n + 3 }
     98  mul2 = ->(n) { n * 2 }
     99
     100  f1 = mul2 << add3
     101  assert_kind_of Proc, f1
     102  assert_equal 16, f1.call(5)
     103
     104  f2 = mul2 >> add3
     105  assert_kind_of Proc, f2
     106  assert_equal 13, f2.call(5)
    69107end
    70108
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-random/src/random.c

    r331 r439  
    1010#include <mruby/data.h>
    1111#include <mruby/array.h>
    12 #include "mt19937ar.h"
     12#include <mruby/istruct.h>
     13#if INT32_MAX <= INTPTR_MAX
     14# define XORSHIFT96
     15# define NSEEDS 3
     16#else
     17# define NSEEDS 4
     18#endif
     19#define LASTSEED (NSEEDS-1)
    1320
    1421#include <time.h>
    1522
    16 static char const MT_STATE_KEY[] = "$mrb_i_mt_state";
    17 
    18 static const struct mrb_data_type mt_state_type = {
    19   MT_STATE_KEY, mrb_free,
    20 };
    21 
    22 static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self);
    23 static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self);
     23typedef struct rand_state {
     24  uint32_t seed[NSEEDS];
     25} rand_state;
    2426
    2527static void
    26 mt_srand(mt_state *t, unsigned long seed)
    27 {
    28   mrb_random_init_genrand(t, seed);
    29 }
    30 
    31 static unsigned long
    32 mt_rand(mt_state *t)
    33 {
    34   return mrb_random_genrand_int32(t);
    35 }
    36 
     28rand_init(rand_state *t)
     29{
     30  t->seed[0] = 123456789;
     31  t->seed[1] = 362436069;
     32  t->seed[2] = 521288629;
     33#ifndef XORSHIFT96
     34  t->seed[3] = 88675123;
     35#endif
     36}
     37
     38static uint32_t
     39rand_seed(rand_state *t, uint32_t seed)
     40{
     41  uint32_t old_seed = t->seed[LASTSEED];
     42  rand_init(t);
     43  t->seed[LASTSEED] = seed;
     44  return old_seed;
     45}
     46
     47#ifdef XORSHIFT96
     48static uint32_t
     49rand_uint32(rand_state *state)
     50{
     51  uint32_t *seed = state->seed;
     52  uint32_t x = seed[0];
     53  uint32_t y = seed[1];
     54  uint32_t z = seed[2];
     55  uint32_t t;
     56
     57  t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6));
     58  x = y; y = z; z = t;
     59  seed[0] = x;
     60  seed[1] = y;
     61  seed[2] = z;
     62
     63  return z;
     64}
     65#else  /* XORSHIFT96 */
     66static uint32_t
     67rand_uint32(rand_state *state)
     68{
     69  uint32_t *seed = state->seed;
     70  uint32_t x = seed[0];
     71  uint32_t y = seed[1];
     72  uint32_t z = seed[2];
     73  uint32_t w = seed[3];
     74  uint32_t t;
     75
     76  t = x ^ (x << 11);
     77  x = y; y = z; z = w;
     78  w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
     79  seed[0] = x;
     80  seed[1] = y;
     81  seed[2] = z;
     82  seed[3] = w;
     83
     84  return w;
     85}
     86#endif  /* XORSHIFT96 */
     87
     88#ifndef MRB_WITHOUT_FLOAT
    3789static double
    38 mt_rand_real(mt_state *t)
    39 {
    40   return mrb_random_genrand_real1(t);
    41 }
    42 
    43 static mrb_value
    44 mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed)
    45 {
    46   if (mrb_nil_p(seed)) {
    47     seed = mrb_fixnum_value((mrb_int)(time(NULL) + mt_rand(t)));
    48     if (mrb_fixnum(seed) < 0) {
    49       seed = mrb_fixnum_value(0 - mrb_fixnum(seed));
    50     }
    51   }
    52 
    53   mt_srand(t, (unsigned) mrb_fixnum(seed));
    54 
    55   return seed;
    56 }
    57 
    58 static mrb_value
    59 mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max)
     90rand_real(rand_state *t)
     91{
     92  uint32_t x = rand_uint32(t);
     93  return x*(1.0/4294967295.0);
     94}
     95#endif
     96
     97static mrb_value
     98random_rand(mrb_state *mrb, rand_state *t, mrb_value max)
    6099{
    61100  mrb_value value;
    62101
    63102  if (mrb_fixnum(max) == 0) {
    64     value = mrb_float_value(mrb, mt_rand_real(t));
    65   }
    66   else {
    67     value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max));
     103#ifndef MRB_WITHOUT_FLOAT
     104    value = mrb_float_value(mrb, rand_real(t));
     105#else
     106    mrb_raise(mrb, E_ARGUMENT_ERROR, "Float not supported");
     107#endif
     108  }
     109  else {
     110    value = mrb_fixnum_value(rand_uint32(t) % mrb_fixnum(max));
    68111  }
    69112
     
    80123
    81124  if (!mrb_nil_p(arg)) {
    82     arg = mrb_check_convert_type(mrb, arg, MRB_TT_FIXNUM, "Fixnum", "to_int");
    83     if (mrb_nil_p(arg)) {
    84       mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument type");
    85     }
    86     if (mrb_fixnum(arg) < 0) {
    87       arg = mrb_fixnum_value(0 - mrb_fixnum(arg));
     125    mrb_int i;
     126
     127    arg = mrb_to_int(mrb, arg);
     128    i = mrb_fixnum(arg);
     129    if (i < 0) {
     130      arg = mrb_fixnum_value(0 - i);
    88131    }
    89132  }
     
    91134}
    92135
    93 static mrb_value
    94 get_random(mrb_state *mrb) {
    95   return mrb_const_get(mrb,
    96              mrb_obj_value(mrb_class_get(mrb, "Random")),
    97              mrb_intern_lit(mrb, "DEFAULT"));
    98 }
    99 
    100 static mt_state *
    101 get_random_state(mrb_state *mrb)
    102 {
    103   mrb_value random_val = get_random(mrb);
    104   return DATA_GET_PTR(mrb, random_val, &mt_state_type, mt_state);
    105 }
    106 
    107 static mrb_value
    108 mrb_random_g_rand(mrb_state *mrb, mrb_value self)
    109 {
    110   mrb_value random = get_random(mrb);
    111   return mrb_random_rand(mrb, random);
    112 }
    113 
    114 static mrb_value
    115 mrb_random_g_srand(mrb_state *mrb, mrb_value self)
    116 {
    117   mrb_value random = get_random(mrb);
    118   return mrb_random_srand(mrb, random);
    119 }
    120 
    121 static mrb_value
    122 mrb_random_init(mrb_state *mrb, mrb_value self)
     136static void
     137random_check(mrb_state *mrb, mrb_value random) {
     138  struct RClass *c = mrb_class_get(mrb, "Random");
     139  if (!mrb_obj_is_kind_of(mrb, random, c) || !mrb_istruct_p(random)) {
     140    mrb_raise(mrb, E_TYPE_ERROR, "Random instance required");
     141  }
     142}
     143
     144static mrb_value
     145random_default(mrb_state *mrb) {
     146  struct RClass *c = mrb_class_get(mrb, "Random");
     147  mrb_value d = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, "DEFAULT"));
     148  if (!mrb_obj_is_kind_of(mrb, d, c)) {
     149    mrb_raise(mrb, E_TYPE_ERROR, "Random::DEFAULT replaced");
     150  }
     151  return d;
     152}
     153
     154#define random_ptr(v) (rand_state*)mrb_istruct_ptr(v)
     155#define random_default_state(mrb) random_ptr(random_default(mrb))
     156
     157static mrb_value
     158random_m_init(mrb_state *mrb, mrb_value self)
    123159{
    124160  mrb_value seed;
    125   mt_state *t;
     161  rand_state *t;
    126162
    127163  seed = get_opt(mrb);
    128 
    129164  /* avoid memory leaks */
    130   t = (mt_state*)DATA_PTR(self);
    131   if (t) {
    132     mrb_free(mrb, t);
    133   }
    134   mrb_data_init(self, NULL, &mt_state_type);
    135 
    136   t = (mt_state *)mrb_malloc(mrb, sizeof(mt_state));
    137   t->mti = N + 1;
    138 
    139   seed = mrb_random_mt_srand(mrb, t, seed);
     165  t = random_ptr(self);
    140166  if (mrb_nil_p(seed)) {
    141     t->has_seed = FALSE;
    142   }
    143   else {
    144     mrb_assert(mrb_fixnum_p(seed));
    145     t->has_seed = TRUE;
    146     t->seed = mrb_fixnum(seed);
    147   }
    148 
    149   mrb_data_init(self, t, &mt_state_type);
     167    rand_init(t);
     168  }
     169  else {
     170    rand_seed(t, (uint32_t)mrb_fixnum(seed));
     171  }
    150172
    151173  return self;
    152174}
    153175
    154 static void
    155 mrb_random_rand_seed(mrb_state *mrb, mt_state *t)
    156 {
    157   if (!t->has_seed) {
    158     mrb_random_mt_srand(mrb, t, mrb_nil_value());
    159   }
    160 }
    161 
    162 static mrb_value
    163 mrb_random_rand(mrb_state *mrb, mrb_value self)
     176static mrb_value
     177random_m_rand(mrb_state *mrb, mrb_value self)
    164178{
    165179  mrb_value max;
    166   mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
     180  rand_state *t = random_ptr(self);
    167181
    168182  max = get_opt(mrb);
    169   mrb_random_rand_seed(mrb, t);
    170   return mrb_random_mt_rand(mrb, t, max);
    171 }
    172 
    173 static mrb_value
    174 mrb_random_srand(mrb_state *mrb, mrb_value self)
    175 {
    176   mrb_value seed;
    177   mrb_value old_seed;
    178   mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
    179 
    180   seed = get_opt(mrb);
    181   seed = mrb_random_mt_srand(mrb, t, seed);
    182   old_seed = t->has_seed? mrb_fixnum_value(t->seed) : mrb_nil_value();
    183   if (mrb_nil_p(seed)) {
    184     t->has_seed = FALSE;
    185   }
    186   else {
    187     mrb_assert(mrb_fixnum_p(seed));
    188     t->has_seed = TRUE;
    189     t->seed = mrb_fixnum(seed);
    190   }
    191 
    192   return old_seed;
     183  return random_rand(mrb, t, max);
     184}
     185
     186static mrb_value
     187random_m_srand(mrb_state *mrb, mrb_value self)
     188{
     189  uint32_t seed;
     190  uint32_t old_seed;
     191  mrb_value sv;
     192  rand_state *t = random_ptr(self);
     193
     194  sv = get_opt(mrb);
     195  if (mrb_nil_p(sv)) {
     196    seed = (uint32_t)time(NULL) + rand_uint32(t);
     197  }
     198  else {
     199    seed = (uint32_t)mrb_fixnum(sv);
     200  }
     201  old_seed = rand_seed(t, seed);
     202
     203  return mrb_fixnum_value((mrb_int)old_seed);
    193204}
    194205
     
    204215{
    205216  mrb_int i;
    206   mt_state *random = NULL;
     217  mrb_value max;
     218  mrb_value r = mrb_nil_value();
     219  rand_state *random;
    207220
    208221  if (RARRAY_LEN(ary) > 1) {
    209     mrb_get_args(mrb, "|d", &random, &mt_state_type);
    210 
    211     if (random == NULL) {
    212       random = get_random_state(mrb);
    213     }
    214     mrb_random_rand_seed(mrb, random);
    215 
     222    mrb_get_args(mrb, "|o", &r);
     223
     224    if (mrb_nil_p(r)) {
     225      random = random_default_state(mrb);
     226    }
     227    else {
     228      random_check(mrb, r);
     229      random = random_ptr(r);
     230    }
    216231    mrb_ary_modify(mrb, mrb_ary_ptr(ary));
    217 
     232    max = mrb_fixnum_value(RARRAY_LEN(ary));
    218233    for (i = RARRAY_LEN(ary) - 1; i > 0; i--)  {
    219234      mrb_int j;
     235      mrb_value *ptr = RARRAY_PTR(ary);
    220236      mrb_value tmp;
    221237
    222       j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary))));
    223 
    224       tmp = RARRAY_PTR(ary)[i];
    225       mrb_ary_ptr(ary)->ptr[i] = RARRAY_PTR(ary)[j];
    226       mrb_ary_ptr(ary)->ptr[j] = tmp;
     238      j = mrb_fixnum(random_rand(mrb, random, max));
     239
     240      tmp = ptr[i];
     241      ptr[i] = ptr[j];
     242      ptr[j] = tmp;
    227243    }
    228244  }
     
    267283  mrb_int n = 0;
    268284  mrb_bool given;
    269   mt_state *random = NULL;
     285  mrb_value r = mrb_nil_value();
     286  rand_state *random;
    270287  mrb_int len;
    271288
    272   mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type);
    273   if (random == NULL) {
    274     random = get_random_state(mrb);
    275   }
    276   mrb_random_rand_seed(mrb, random);
    277   mt_rand(random);
     289  mrb_get_args(mrb, "|i?o", &n, &given, &r);
     290  if (mrb_nil_p(r)) {
     291    random = random_default_state(mrb);
     292  }
     293  else {
     294    random_check(mrb, r);
     295    random = random_ptr(r);
     296  }
    278297  len = RARRAY_LEN(ary);
    279298  if (!given) {                 /* pick one element */
     
    284303      return RARRAY_PTR(ary)[0];
    285304    default:
    286       return RARRAY_PTR(ary)[mt_rand(random) % len];
     305      return RARRAY_PTR(ary)[rand_uint32(random) % len];
    287306    }
    288307  }
     
    299318      for (;;) {
    300319      retry:
    301         r = mt_rand(random) % len;
     320        r = (mrb_int)(rand_uint32(random) % len);
    302321
    303322        for (j=0; j<i; j++) {
     
    317336}
    318337
     338static mrb_value
     339random_f_rand(mrb_state *mrb, mrb_value self)
     340{
     341  rand_state *t = random_default_state(mrb);
     342  return random_rand(mrb, t, get_opt(mrb));
     343}
     344
     345static mrb_value
     346random_f_srand(mrb_state *mrb, mrb_value self)
     347{
     348  mrb_value random = random_default(mrb);
     349  return random_m_srand(mrb, random);
     350}
     351
    319352
    320353void mrb_mruby_random_gem_init(mrb_state *mrb)
     
    323356  struct RClass *array = mrb->array_class;
    324357
    325   mrb_define_method(mrb, mrb->kernel_module, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));
    326   mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
     358  mrb_assert(sizeof(rand_state) <= ISTRUCT_DATA_SIZE);
     359
     360  mrb_define_method(mrb, mrb->kernel_module, "rand", random_f_rand, MRB_ARGS_OPT(1));
     361  mrb_define_method(mrb, mrb->kernel_module, "srand", random_f_srand, MRB_ARGS_OPT(1));
    327362
    328363  random = mrb_define_class(mrb, "Random", mrb->object_class);
    329   MRB_SET_INSTANCE_TT(random, MRB_TT_DATA);
    330   mrb_define_class_method(mrb, random, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));
    331   mrb_define_class_method(mrb, random, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
    332 
    333   mrb_define_method(mrb, random, "initialize", mrb_random_init, MRB_ARGS_OPT(1));
    334   mrb_define_method(mrb, random, "rand", mrb_random_rand, MRB_ARGS_OPT(1));
    335   mrb_define_method(mrb, random, "srand", mrb_random_srand, MRB_ARGS_OPT(1));
     364  MRB_SET_INSTANCE_TT(random, MRB_TT_ISTRUCT);
     365  mrb_define_class_method(mrb, random, "rand", random_f_rand, MRB_ARGS_OPT(1));
     366  mrb_define_class_method(mrb, random, "srand", random_f_srand, MRB_ARGS_OPT(1));
     367
     368  mrb_define_method(mrb, random, "initialize", random_m_init, MRB_ARGS_OPT(1));
     369  mrb_define_method(mrb, random, "rand", random_m_rand, MRB_ARGS_OPT(1));
     370  mrb_define_method(mrb, random, "srand", random_m_srand, MRB_ARGS_OPT(1));
    336371
    337372  mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1));
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-random/test/random.rb

    r331 r439  
    22# Random Test
    33
    4 assert("Random#srand") do
     4assert("Random.new") do
    55  r1 = Random.new(123)
    66  r2 = Random.new(123)
    7   r1.rand == r2.rand
     7  r3 = Random.new(124)
     8  assert_equal(r1.rand, r2.rand)
     9  assert_not_equal(r1.rand, r3.rand)
    810end
    911
    10 assert("Kernel::srand") do
     12assert("Kernel.srand") do
    1113  srand(234)
    1214  r1 = rand
    1315  srand(234)
    1416  r2 = rand
    15   r1 == r2
     17  srand(235)
     18  r3 = rand
     19  assert_equal(r1, r2)
     20  assert_not_equal(r1, r3)
    1621end
    1722
    18 assert("Random::srand") do
     23assert("Random.srand") do
    1924  Random.srand(345)
    2025  r1 = rand
    2126  srand(345)
    2227  r2 = Random.rand
    23   r1 == r2
     28  Random.srand(346)
     29  r3 = rand
     30  assert_equal(r1, r2)
     31  assert_not_equal(r1, r3)
    2432end
    2533
    26 assert("fixnum") do
    27   rand(3).class == Fixnum
    28 end
    29 
    30 assert("float") do
    31   rand.class == Float
     34assert("return class of Kernel.rand") do
     35  assert_kind_of(Fixnum, rand(3))
     36  assert_kind_of(Fixnum, rand(1.5))
     37  assert_kind_of(Float, rand)
     38  assert_kind_of(Float, rand(0.5))
    3239end
    3340
    3441assert("Array#shuffle") do
    35   ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     42  orig = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     43  ary = orig.dup
    3644  shuffled = ary.shuffle
    37 
    38   ary == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and shuffled != ary and 10.times { |x| ary.include? x }
     45  assert_equal(orig, ary)
     46  assert_not_equal(ary, shuffled)
     47  assert_equal(orig, shuffled.sort)
    3948end
    4049
    4150assert('Array#shuffle!') do
    42   ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    43   ary.shuffle!
    44 
    45   ary != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary.include? x }
     51  orig = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     52  ary = orig.dup
     53  assert_same(ary, ary.shuffle!)
     54  assert_not_equal(orig, ary)
     55  assert_equal(orig, ary.sort)
    4656end
    4757
     
    5363
    5464  # verify that the same seed causes the same results
    55   ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    56   shuffle1 = ary1.shuffle Random.new 345
    57   ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    58   shuffle2 = ary2.shuffle Random.new 345
    59 
    60   ary1 != shuffle1 and 10.times { |x| shuffle1.include? x } and shuffle1 == shuffle2
     65  ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     66  shuffled1 = ary.shuffle Random.new 345
     67  shuffled2 = ary.shuffle Random.new 345
     68  shuffled3 = ary.shuffle Random.new 346
     69  assert_equal(shuffled1, shuffled2)
     70  assert_not_equal(shuffled1, shuffled3)
    6171end
    6272
     
    7282  ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    7383  ary2.shuffle! Random.new 345
    74 
    75   ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2
     84  ary3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     85  ary3.shuffle! Random.new 346
     86  assert_equal(ary1, ary2)
     87  assert_not_equal(ary1, ary3)
    7688end
    7789
    78 assert('Array#sample checks input length after reading arguments') do
    79   $ary = [1, 2, 3]
    80   class ArrayChange
    81     def to_i
    82       $ary << 4
    83       4
     90assert('Array#sample') do
     91  100.times do
     92    assert_include([0, 1, 2], [2, 1, 0].sample)
     93    [2, 1, 0].sample(2).each { |sample| assert_include([0, 1, 2], sample) }
     94    h = {}
     95    (1..10).to_a.sample(7).each do |sample|
     96      assert_not_include(h, sample)
     97      h[sample] = true
    8498    end
    8599  end
    86100
    87   assert_equal [1, 2, 3, 4], $ary.sample(ArrayChange.new).sort
     101  assert_nil([].sample)
     102  assert_equal([], [].sample(1))
     103  assert_equal([], [2, 1].sample(0))
     104  assert_raise(TypeError) { [2, 1].sample(true) }
     105  assert_raise(ArgumentError) { [2, 1].sample(-1) }
    88106end
     107
     108assert('Array#sample(random)') do
     109  assert_raise(TypeError) do
     110    # this will cause an exception due to the wrong argument
     111    [1, 2].sample(2, "Not a Random instance")
     112  end
     113
     114  # verify that the same seed causes the same results
     115  ary = (1..10).to_a
     116  srand(15)
     117  samples1 = ary.sample(4)
     118  samples2 = ary.sample(4, Random.new(15))
     119  samples3 = ary.sample(4, Random.new(16))
     120  assert_equal(samples1, samples2)
     121  assert_not_equal(samples1, samples3)
     122end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-range-ext/mrblib/range.rb

    r331 r439  
    1616    raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1)" unless args.length == 1
    1717    nv = args[0]
    18     raise TypeError, "no implicit conversion from nil to integer" if nv.nil?
    19     raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless nv.respond_to?(:to_int)
    20     n = nv.to_int
    21     raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless n.kind_of?(Integer)
     18    n = nv.__to_int
    2219    raise ArgumentError, "negative array size (or size too big)" unless 0 <= n
    2320    ary = []
     
    2926    ary
    3027  end
     28
     29  def max(&block)
     30    val = self.first
     31    last = self.last
     32    return super if block
     33
     34    # fast path for numerics
     35    if val.kind_of?(Numeric) && last.kind_of?(Numeric)
     36      raise TypeError if exclude_end? && !last.kind_of?(Fixnum)
     37      return nil if val > last
     38      return nil if val == last && exclude_end?
     39
     40      max = last
     41      max -= 1 if exclude_end?
     42      return max
     43    end
     44
     45    # delegate to Enumerable
     46    super
     47  end
     48
     49  def min(&block)
     50    val = self.first
     51    last = self.last
     52    return super if block
     53
     54    # fast path for numerics
     55    if val.kind_of?(Numeric) && last.kind_of?(Numeric)
     56      return nil if val > last
     57      return nil if val == last && exclude_end?
     58
     59      min = val
     60      return min
     61    end
     62
     63    # delegate to Enumerable
     64    super
     65  end
    3166end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-range-ext/src/range.c

    r331 r439  
    22#include <mruby/range.h>
    33#include <math.h>
    4 #include <float.h>
    54
    65static mrb_bool
    76r_le(mrb_state *mrb, mrb_value a, mrb_value b)
    87{
    9   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
    10   /* output :a < b => -1, a = b =>  0, a > b => +1 */
     8  mrb_int n = mrb_cmp(mrb, a, b);
    119
    12   if (mrb_fixnum_p(r)) {
    13     mrb_int c = mrb_fixnum(r);
    14     if (c == 0 || c == -1) return TRUE;
    15   }
    16 
     10  if (n == 0 || n == -1) return TRUE;
    1711  return FALSE;
    1812}
     
    2115r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
    2216{
    23   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
    24   /* output :a < b => -1, a = b =>  0, a > b => +1 */
    25 
    26   return mrb_fixnum_p(r) && mrb_fixnum(r) == -1;
     17  return mrb_cmp(mrb, a, b) == -1;
    2718}
    2819
     
    4233 */
    4334static mrb_value
    44 mrb_range_cover(mrb_state *mrb, mrb_value range)
     35range_cover(mrb_state *mrb, mrb_value range)
    4536{
    4637  mrb_value val;
     
    5041  mrb_get_args(mrb, "o", &val);
    5142
    52   beg = r->edges->beg;
    53   end = r->edges->end;
     43  beg = RANGE_BEG(r);
     44  end = RANGE_END(r);
    5445
    5546  if (r_le(mrb, beg, val)) {
    56     if (r->excl) {
     47    if (RANGE_EXCL(r)) {
    5748      if (r_lt(mrb, val, end))
    5849        return mrb_true_value();
     
    8475 */
    8576static mrb_value
    86 mrb_range_last(mrb_state *mrb, mrb_value range)
     77range_last(mrb_state *mrb, mrb_value range)
    8778{
    8879  mrb_value num;
    8980  mrb_value array;
    90   struct RRange *r = mrb_range_ptr(mrb, range);
    9181
    9282  if (mrb_get_args(mrb, "|o", &num) == 0) {
    93     return r->edges->end;
     83    return mrb_range_end(mrb, range);
    9484  }
    9585
     
    10999 */
    110100
     101#ifndef MRB_WITHOUT_FLOAT
    111102static mrb_value
    112 mrb_range_size(mrb_state *mrb, mrb_value range)
     103range_size(mrb_state *mrb, mrb_value range)
    113104{
    114105  struct RRange *r = mrb_range_ptr(mrb, range);
     
    118109  mrb_bool excl;
    119110
    120   beg = r->edges->beg;
    121   end = r->edges->end;
    122   excl = r->excl;
     111  beg = RANGE_BEG(r);
     112  end = RANGE_END(r);
     113  excl = RANGE_EXCL(r);
    123114  if (mrb_fixnum_p(beg)) {
    124115    beg_f = (mrb_float)mrb_fixnum(beg);
     
    161152  return mrb_nil_value();
    162153}
     154#else
     155static mrb_value
     156range_size(mrb_state *mrb, mrb_value range)
     157{
     158  struct RRange *r = mrb_range_ptr(mrb, range);
     159  mrb_value beg, end;
     160  mrb_int excl;
     161
     162  beg = RANGE_BEG(r);
     163  end = RANGE_END(r);
     164  excl = RANGE_EXCL(r) ? 0 : 1;
     165
     166  if (mrb_fixnum_p(beg) && mrb_fixnum_p(end)) {
     167    mrb_int a = mrb_fixnum(beg);
     168    mrb_int b = mrb_fixnum(end);
     169    mrb_int c = b - a + excl;
     170
     171    return mrb_fixnum_value(c);
     172  }
     173  return mrb_nil_value();
     174}
     175#endif /* MRB_WITHOUT_FLOAT */
    163176
    164177void
     
    167180  struct RClass * s = mrb_class_get(mrb, "Range");
    168181
    169   mrb_define_method(mrb, s, "cover?", mrb_range_cover, MRB_ARGS_REQ(1));
    170   mrb_define_method(mrb, s, "last",   mrb_range_last,  MRB_ARGS_OPT(1));
    171   mrb_define_method(mrb, s, "size",   mrb_range_size,  MRB_ARGS_NONE());
     182  mrb_define_method(mrb, s, "cover?", range_cover, MRB_ARGS_REQ(1));
     183  mrb_define_method(mrb, s, "last",   range_last,  MRB_ARGS_OPT(1));
     184  mrb_define_method(mrb, s, "size",   range_size,  MRB_ARGS_NONE());
    172185}
    173186
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-range-ext/test/range.rb

    r331 r439  
    1111  assert_equal 10, (10..20).first
    1212  assert_equal [10, 11, 12], (10..20).first(3)
     13
     14  skip unless Object.const_defined?(:Float)
    1315  assert_equal [0, 1, 2], (0..Float::INFINITY).first(3)
    1416end
     
    2426  assert_equal 42, (1..42).size
    2527  assert_equal 41, (1...42).size
     28  assert_nil ('a'..'z').size
     29
     30  skip unless Object.const_defined?(:Float)
    2631  assert_equal 6, (1...6.3).size
    2732  assert_equal 5, (1...6.0).size
     
    2934  assert_equal 15, (1.0..15.9).size
    3035  assert_equal Float::INFINITY, (0..Float::INFINITY).size
    31   assert_nil ('a'..'z').size
    3236end
     37
     38assert('Range#max') do
     39  # returns the maximum value in the range when called with no arguments
     40  assert_equal 10, (1..10).max
     41  assert_equal 9, (1...10).max
     42  assert_equal 536870911, (0...2**29).max
     43
     44  # returns nil when the endpoint is less than the start point
     45  assert_equal nil, (100..10).max
     46
     47  # returns nil when the endpoint equals the start point and the range is exclusive
     48  assert_equal nil, (5...5).max
     49
     50  # returns the endpoint when the endpoint equals the start point and the range is inclusive
     51  assert_equal 5, (5..5).max
     52
     53  skip unless Object.const_defined?(:Float)
     54
     55  # returns the maximum value in the Float range when called with no arguments
     56  assert_equal 908.1111, (303.20..908.1111).max
     57
     58  # raises TypeError when called on an exclusive range and a non Integer value
     59  assert_raise(TypeError) { (303.20...908.1111).max }
     60
     61  # returns nil when the endpoint is less than the start point in a Float range
     62  assert_equal nil, (3003.20..908.1111).max
     63end
     64
     65assert('Range#max given a block') do
     66  # passes each pair of values in the range to the block
     67  acc = []
     68  (1..10).max do |a, b|
     69    acc << a
     70    acc << b
     71    a
     72  end
     73  (1..10).each do |value|
     74    assert_true acc.include?(value)
     75  end
     76
     77  # passes each pair of elements to the block in reversed order
     78  acc = []
     79  (1..5).max do |a, b|
     80    acc << [a, b]
     81    a
     82  end
     83  assert_equal [[2, 1], [3, 2], [4, 3], [5, 4]], acc
     84
     85  # returns the element the block determines to be the maximum
     86  assert_equal 1, ((1..3).max { |_a, _b| -3 })
     87
     88  # returns nil when the endpoint is less than the start point
     89  assert_equal nil, ((100..10).max { |x, y| x <=> y })
     90  assert_equal nil, ((5...5).max { |x, y| x <=> y })
     91end
     92
     93assert('Range#min') do
     94  # returns the minimum value in the range when called with no arguments
     95  assert_equal 1, (1..10).min
     96  assert_equal 1, (1...10).min
     97
     98  # returns nil when the start point is greater than the endpoint
     99  assert_equal nil, (100..10).min
     100
     101  # returns nil when the endpoint equals the start point and the range is exclusive
     102  assert_equal nil, (5...5).max
     103
     104  # returns the endpoint when the endpoint equals the start point and the range is inclusive
     105  assert_equal 5, (5..5).max
     106
     107  skip unless Object.const_defined?(:Float)
     108
     109  # returns the minimum value in the Float range when called with no arguments
     110  assert_equal 303.20, (303.20..908.1111).min
     111
     112  # returns nil when the start point is greater than the endpoint in a Float range
     113  assert_equal nil, (3003.20..908.1111).max
     114end
     115
     116assert('Range#min given a block') do
     117  # passes each pair of values in the range to the block
     118  acc = []
     119  (1..10).min do |a, b|
     120    acc << a
     121    acc << b
     122    a
     123  end
     124  (1..10).each do |value|
     125    assert_true acc.include?(value)
     126  end
     127
     128  # passes each pair of elements to the block in reversed order
     129  acc = []
     130  (1..5).min do |a, b|
     131    acc << [a, b]
     132    a
     133  end
     134  assert_equal [[2, 1], [3, 1], [4, 1], [5, 1]], acc
     135
     136  # returns the element the block determines to be the minimum
     137  assert_equal 3, ((1..3).min { |_a, _b| -3 })
     138
     139  # returns nil when the start point is greater than the endpoint
     140  assert_equal nil, ((100..10).min { |x, y| x <=> y })
     141  assert_equal nil, ((5...5).min { |x, y| x <=> y })
     142end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-sprintf/src/kernel.c

    r331 r439  
    1919  krn = mrb->kernel_module;
    2020
    21   mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_ANY());
    22   mrb_define_method(mrb, krn, "format",  mrb_f_sprintf, MRB_ARGS_ANY());
     21  mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST());
     22  mrb_define_method(mrb, krn, "format",  mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST());
    2323}
    2424
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-sprintf/src/sprintf.c

    r331 r439  
    77#include <mruby.h>
    88
     9#ifdef MRB_DISABLE_STDIO
     10# error sprintf conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
     11#endif
     12
    913#include <limits.h>
    10 #include <stdio.h>
    1114#include <string.h>
    1215#include <mruby/string.h>
    1316#include <mruby/hash.h>
    1417#include <mruby/numeric.h>
     18#ifndef MRB_WITHOUT_FLOAT
    1519#include <math.h>
     20#endif
    1621#include <ctype.h>
    1722
     
    2025#define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n)))
    2126
    22 mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value);
     27mrb_value mrb_str_format(mrb_state *, mrb_int, const mrb_value *, mrb_value);
     28#ifndef MRB_WITHOUT_FLOAT
    2329static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int);
     30#endif
    2431
    2532static char*
     
    7885
    7986  if (base != 2) {
    80     mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base));
     87    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base);
    8188  }
    8289  if (val == 0) {
     
    116123
    117124#define CHECK(l) do {\
    118 /*  int cr = ENC_CODERANGE(result);*/\
    119125  while ((l) >= bsiz - blen) {\
     126    if (bsiz > MRB_INT_MAX/2) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \
    120127    bsiz*=2;\
    121     if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \
    122128  }\
    123129  mrb_str_resize(mrb, result, bsiz);\
    124 /*  ENC_CODERANGE_SET(result, cr);*/\
    125130  buf = RSTRING_PTR(result);\
    126131} while (0)
     
    129134  CHECK(l);\
    130135  memcpy(&buf[blen], s, l);\
    131   blen += (l);\
     136  blen += (mrb_int)(l);\
    132137} while (0)
    133138
     
    143148  switch (posarg) {
    144149  case -1:
    145     mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg));
     150    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg);
    146151    break;
    147152  case -2:
    148     mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg));
     153    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg);
    149154    break;
    150155  default:
     
    154159
    155160static void
    156 check_pos_arg(mrb_state *mrb, int posarg, int n)
     161check_pos_arg(mrb_state *mrb, int posarg, mrb_int n)
    157162{
    158163  if (posarg > 0) {
    159     mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)",
    160                mrb_fixnum_value(n), mrb_fixnum_value(posarg));
     164    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after unnumbered(%d)",
     165               n, posarg);
    161166  }
    162167  if (posarg == -2) {
    163     mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n));
     168    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after named", n);
    164169  }
    165170  if (n < 1) {
    166     mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n));
     171    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %i$", n);
    167172  }
    168173}
    169174
    170175static void
    171 check_name_arg(mrb_state *mrb, int posarg, const char *name, int len)
     176check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len)
    172177{
    173178  if (posarg > 0) {
    174     mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)",
    175                mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg));
     179    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after unnumbered(%d)",
     180               name, len, posarg);
    176181  }
    177182  if (posarg == -1) {
    178     mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len)));
     183    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after numbered", name, len);
    179184  }
    180185}
     
    199204#define GETNUM(n, val) \
    200205  for (; p < end && ISDIGIT(*p); p++) {\
    201     int next_n = 10 * n + (*p - '0'); \
    202     if (next_n / 10 != n) {\
     206    if (n > (MRB_INT_MAX - (*p - '0'))/10) {\
    203207      mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \
    204208    } \
    205     n = next_n; \
     209    n = 10 * n + (*p - '0'); \
    206210  } \
    207211  if (p >= end) { \
     
    225229
    226230static mrb_value
    227 get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
     231get_hash(mrb_state *mrb, mrb_value *hash, mrb_int argc, const mrb_value *argv)
    228232{
    229233  mrb_value tmp;
     
    233237    mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required");
    234238  }
    235   tmp = mrb_check_convert_type(mrb, argv[1], MRB_TT_HASH, "Hash", "to_hash");
     239  tmp = mrb_check_hash_type(mrb, argv[1]);
    236240  if (mrb_nil_p(tmp)) {
    237241    mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required");
     
    519523
    520524mrb_value
    521 mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
     525mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt)
    522526{
    523527  const char *p, *end;
     
    529533  mrb_int width;
    530534  mrb_int prec;
    531   int flags = FNONE;
    532535  int nextarg = 1;
    533536  int posarg = 0;
     
    553556  ++argc;
    554557  --argv;
    555   fmt = mrb_str_to_str(mrb, fmt);
     558  mrb_to_str(mrb, fmt);
    556559  p = RSTRING_PTR(fmt);
    557560  end = p + RSTRING_LEN(fmt);
    558561  blen = 0;
    559562  bsiz = 120;
    560   result = mrb_str_buf_new(mrb, bsiz);
     563  result = mrb_str_new_capa(mrb, bsiz);
    561564  buf = RSTRING_PTR(result);
    562565  memset(buf, 0, bsiz);
     
    565568    const char *t;
    566569    mrb_sym id = 0;
     570    int flags = FNONE;
    567571
    568572    for (t = p; t < end && *t != '%'; t++) ;
     
    580584    switch (*p) {
    581585      default:
    582         mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1));
     586        mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p);
    583587        break;
    584588
     
    619623        if (*p == '$') {
    620624          if (!mrb_undef_p(nextvalue)) {
    621             mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %S$", mrb_fixnum_value(n));
     625            mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %i$", n);
    622626          }
    623627          nextvalue = GETPOSARG(n);
     
    639643          p++;
    640644        if (id) {
    641           mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%S after <%S>",
    642                      mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id));
     645          mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%l after <%n>",
     646                     start, p - start + 1, id);
    643647        }
    644648        symname = mrb_str_new(mrb, start + 1, p - start - 1);
    645649        id = mrb_intern_str(mrb, symname);
    646         nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1));
     650        nextvalue = GETNAMEARG(mrb_symbol_value(id), start, p - start + 1);
    647651        if (mrb_undef_p(nextvalue)) {
    648           mrb_raisef(mrb, E_KEY_ERROR, "key%S not found", mrb_str_new(mrb, start, p - start + 1));
     652          mrb_raisef(mrb, E_KEY_ERROR, "key%l not found", start, p - start + 1);
    649653        }
    650654        if (term == '}') goto format_s;
     
    702706        tmp = mrb_check_string_type(mrb, val);
    703707        if (!mrb_nil_p(tmp)) {
    704           if (mrb_fixnum(mrb_funcall(mrb, tmp, "size", 0)) != 1 ) {
     708          if (RSTRING_LEN(tmp) != 1) {
    705709            mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character");
    706710          }
    707711        }
    708712        else if (mrb_fixnum_p(val)) {
    709           tmp = mrb_funcall(mrb, val, "chr", 0);
     713          mrb_int n = mrb_fixnum(val);
     714
     715          if (n < 0x80) {
     716            char buf[1];
     717
     718            buf[0] = (char)n;
     719            tmp = mrb_str_new(mrb, buf, 1);
     720          }
     721          else {
     722            tmp = mrb_funcall(mrb, val, "chr", 0);
     723            mrb_check_type(mrb, tmp, MRB_TT_STRING);
     724          }
    710725        }
    711726        else {
    712727          mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character");
    713728        }
    714         mrb_check_type(mrb, tmp, MRB_TT_STRING);
    715729        c = RSTRING_PTR(tmp);
    716730        n = RSTRING_LEN(tmp);
     
    756770            char *p = RSTRING_PTR(str) + prec;
    757771            slen = prec;
    758             len = p - RSTRING_PTR(str);
     772            len = (mrb_int)(p - RSTRING_PTR(str));
    759773          }
    760774          /* need to adjust multi-byte string pos */
     
    792806        mrb_int len;
    793807
    794         switch (*p) {
    795           case 'd':
    796           case 'i':
    797             sign = 1; break;
    798           default:
    799             break;
    800         }
    801808        if (flags & FSHARP) {
    802809          switch (*p) {
     
    812819  bin_retry:
    813820        switch (mrb_type(val)) {
     821#ifndef MRB_WITHOUT_FLOAT
    814822          case MRB_TT_FLOAT:
    815823            val = mrb_flo_to_fixnum(mrb, val);
    816824            if (mrb_fixnum_p(val)) goto bin_retry;
    817825            break;
     826#endif
    818827          case MRB_TT_STRING:
    819828            val = mrb_str_to_inum(mrb, val, 0, TRUE);
     
    839848          case 'd':
    840849          case 'i':
     850            sign = 1;
     851            /* fall through */
    841852          default:
    842853            base = 10; break;
    843854        }
    844855
    845         if (base == 2) {
    846           if (v < 0 && !sign) {
    847             val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
    848             dots = 1;
    849           }
    850           else {
    851             val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
    852           }
    853         }
    854856        if (sign) {
    855           if (v > 0) {
     857          if (v >= 0) {
    856858            if (flags & FPLUS) {
    857859              sc = '+';
     
    863865            }
    864866          }
     867          else {
     868            sc = '-';
     869            width--;
     870          }
     871          mrb_assert(base == 10);
     872          snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v);
     873          s = nbuf;
     874          if (v < 0) s++;       /* skip minus sign */
     875        }
     876        else {
     877          s = nbuf;
     878          if (v < 0) {
     879            dots = 1;
     880          }
    865881          switch (base) {
    866882          case 2:
    867             strncpy(nbuf, RSTRING_PTR(val), sizeof(nbuf));
    868             break;
    869           case 8:
    870             snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIo, v);
    871             break;
    872           case 10:
    873             snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v);
    874             break;
    875           case 16:
    876             snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIx, v);
    877             break;
    878           }
    879           s = nbuf;
    880         }
    881         else {
    882           s = nbuf;
    883           if (base != 10 && v < 0) {
    884             dots = 1;
    885           }
    886           switch (base) {
    887           case 2:
     883            if (v < 0) {
     884              val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
     885            }
     886            else {
     887              val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
     888            }
    888889            strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1);
    889890            break;
    890891          case 8:
    891892            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v);
    892             break;
    893           case 10:
    894             snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v);
    895893            break;
    896894          case 16:
     
    921919        }
    922920
    923         if (dots) {
    924           prec -= 2;
    925           width -= 2;
    926         }
    927 
    928921        if (*p == 'X') {
    929922          char *pp = s;
     
    973966        if (!(flags&FMINUS) && width > 0) {
    974967          FILL(' ', width);
     968          width = 0;
    975969        }
    976970
     
    981975          PUSH(prefix, plen);
    982976        }
    983         if (dots) PUSH("..", 2);
     977        if (dots) {
     978          prec -= 2;
     979          width -= 2;
     980          PUSH("..", 2);
     981        }
    984982
    985983        if (prec > len) {
    986984          CHECK(prec - len);
    987           if (v < 0) {
     985          if ((flags & (FMINUS|FPREC)) != FMINUS) {
     986            char c = '0';
     987            FILL(c, prec - len);
     988          } else if (v < 0) {
    988989            char c = sign_bits(base, p);
    989             FILL(c, prec - len);
    990           }
    991           else if ((flags & (FMINUS|FPREC)) != FMINUS) {
    992             char c = '0';
    993990            FILL(c, prec - len);
    994991          }
     
    1001998      break;
    1002999
     1000#ifndef MRB_WITHOUT_FLOAT
    10031001      case 'f':
    10041002      case 'g':
     
    10101008        mrb_value val = GETARG();
    10111009        double fval;
    1012         int i, need = 6;
     1010        mrb_int need = 6;
    10131011        char fbuf[32];
    10141012
     
    10161014        if (!isfinite(fval)) {
    10171015          const char *expr;
    1018           const int elen = 3;
     1016          const mrb_int elen = 3;
    10191017          char sign = '\0';
    10201018
     
    10311029            sign = (flags & FPLUS) ? '+' : ' ';
    10321030          if (sign)
    1033             ++need;
     1031            ++need;
    10341032          if ((flags & FWIDTH) && need < width)
    10351033            need = width;
     
    10551053        need = 0;
    10561054        if (*p != 'e' && *p != 'E') {
    1057           i = INT_MIN;
     1055          int i;
    10581056          frexp(fval, &i);
    10591057          if (i > 0)
    10601058            need = BIT_DIGITS(i);
    10611059        }
     1060        if (need > MRB_INT_MAX - ((flags&FPREC) ? prec : 6)) {
     1061        too_big_width:
     1062          mrb_raise(mrb, E_ARGUMENT_ERROR,
     1063                    (width > prec ? "width too big" : "prec too big"));
     1064        }
    10621065        need += (flags&FPREC) ? prec : 6;
    10631066        if ((flags&FWIDTH) && need < width)
    10641067          need = width;
     1068        if (need > MRB_INT_MAX - 20) {
     1069          goto too_big_width;
     1070        }
    10651071        need += 20;
    1066         if (need <= 0) {
    1067           mrb_raise(mrb, E_ARGUMENT_ERROR,
    1068                     (width > prec ? "width too big" : "prec too big"));
    1069         }
    10701072
    10711073        CHECK(need);
    10721074        n = snprintf(&buf[blen], need, fbuf, fval);
    1073         if (n < 0) {
     1075        if (n < 0 || n >= need) {
    10741076          mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error");
    10751077        }
     
    10771079      }
    10781080      break;
     1081#endif
    10791082    }
    10801083    flags = FNONE;
     
    10881091    const char *mesg = "too many arguments for format string";
    10891092    if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg);
    1090     if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%S", mrb_str_new_cstr(mrb, mesg));
     1093    if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%s", mesg);
    10911094  }
    10921095#endif
     
    10961099}
    10971100
     1101#ifndef MRB_WITHOUT_FLOAT
    10981102static void
    10991103fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec)
     
    11221126  *buf = '\0';
    11231127}
     1128#endif
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-sprintf/test/sprintf.rb

    r331 r439  
    44assert('String#%') do
    55  assert_equal "one=1", "one=%d" % 1
    6   assert_equal "1 one 1.0", "%d %s %3.1f" % [ 1, "one", 1.01 ]
     6  assert_equal "1 one", "%d %s" % [ 1, "one" ]
    77  assert_equal "123 < 456", "%{num} < %<str>s" % { num: 123, str: "456" }
    88  assert_equal 15, ("%b" % (1<<14)).size
     9  skip unless Object.const_defined?(:Float)
     10  assert_equal "1.0", "%3.1f" % 1.01
    911end
    1012
    1113assert('String#% with inf') do
     14  skip unless Object.const_defined?(:Float)
    1215  inf = Float::INFINITY
    1316
     
    3841
    3942assert('String#% with nan') do
     43  skip unless Object.const_defined?(:Float)
    4044  nan = Float::NAN
    4145
     
    7680
    7781    assert_raise TypeError do
    78       "%c" % 0
     82      "%c" % 0x80
    7983    end
    8084  ensure
     
    9296end
    9397
     98assert("String#% %d") do
     99  assert_equal("  10",   "%4d" % 10)
     100  assert_equal("1000",   "%4d" % 1000)
     101  assert_equal("10000",  "%4d" % 10000)
     102end
     103
    94104assert("String#% invalid format") do
    95105  assert_raise ArgumentError do
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/mrbgem.rake

    r331 r439  
    33  spec.author  = 'mruby developers'
    44  spec.summary = 'String class extension'
    5   spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator'
    65end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/mrblib/string.rb

    r331 r439  
    11class String
    2 
    3   ##
    4   #  call-seq:
    5   #     String.try_convert(obj) -> string or nil
    6   #
    7   # Try to convert <i>obj</i> into a String, using to_str method.
    8   # Returns converted string or nil if <i>obj</i> cannot be converted
    9   # for any reason.
    10   #
    11   #     String.try_convert("str")     #=> "str"
    12   #     String.try_convert(/re/)      #=> nil
    13   #
    14   def self.try_convert(obj)
    15     if obj.respond_to?(:to_str)
    16       obj.to_str
    17     else
    18       nil
    19     end
    20   end
    212
    223  ##
     
    9677  #
    9778  def lstrip!
    98     raise RuntimeError, "can't modify frozen String" if frozen?
     79    raise FrozenError, "can't modify frozen String" if frozen?
    9980    s = self.lstrip
    10081    (s == self) ? nil : self.replace(s)
     
    11394  #
    11495  def rstrip!
    115     raise RuntimeError, "can't modify frozen String" if frozen?
     96    raise FrozenError, "can't modify frozen String" if frozen?
    11697    s = self.rstrip
    11798    (s == self) ? nil : self.replace(s)
     
    126107  #
    127108  def strip!
    128     raise RuntimeError, "can't modify frozen String" if frozen?
     109    raise FrozenError, "can't modify frozen String" if frozen?
    129110    s = self.strip
    130111    (s == self) ? nil : self.replace(s)
     
    143124  #
    144125  def casecmp(str)
    145     self.downcase <=> str.to_str.downcase
     126    self.downcase <=> str.__to_str.downcase
    146127  rescue NoMethodError
    147     raise TypeError, "no implicit conversion of #{str.class} into String"
     128    nil
     129  end
     130
     131  ##
     132  # call-seq:
     133  #   str.casecmp?(other)  -> true, false, or nil
     134  #
     135  # Returns true if str and other_str are equal after case folding,
     136  # false if they are not equal, and nil if other_str is not a string.
     137
     138  def casecmp?(str)
     139    c = self.casecmp(str)
     140    return nil if c.nil?
     141    return c == 0
    148142  end
    149143
     
    187181  #
    188182  def slice!(arg1, arg2=nil)
    189     raise RuntimeError, "can't modify frozen String" if frozen?
     183    raise FrozenError, "can't modify frozen String" if frozen?
    190184    raise "wrong number of arguments (for 1..2)" if arg1.nil? && arg2.nil?
    191185
     
    317311  end
    318312
     313  ##
     314  # Call the given block for each character of
     315  # +self+.
    319316  def each_char(&block)
    320317    return to_enum :each_char unless block
    321 
    322     split('').each do |i|
    323       block.call(i)
     318    pos = 0
     319    while pos < self.size
     320      block.call(self[pos])
     321      pos += 1
    324322    end
    325323    self
     
    353351    self
    354352  end
     353
     354  ##
     355  #  call-seq:
     356  #    string.lines                ->  array of string
     357  #    string.lines {|s| block}    ->  array of string
     358  #
     359  #  Returns strings per line;
     360  #
     361  #    a = "abc\ndef"
     362  #    a.lines    #=> ["abc\n", "def"]
     363  #
     364  #  If a block is given, it works the same as <code>each_line</code>.
     365  def lines(&blk)
     366    lines = self.__lines
     367    if blk
     368      lines.each do |line|
     369        blk.call(line)
     370      end
     371    end
     372    lines
     373  end
     374
     375  ##
     376  #  call-seq:
     377  #     str.upto(other_str, exclusive=false) {|s| block }   -> str
     378  #     str.upto(other_str, exclusive=false)                -> an_enumerator
     379  #
     380  #  Iterates through successive values, starting at <i>str</i> and
     381  #  ending at <i>other_str</i> inclusive, passing each value in turn to
     382  #  the block. The <code>String#succ</code> method is used to generate
     383  #  each value.  If optional second argument exclusive is omitted or is false,
     384  #  the last value will be included; otherwise it will be excluded.
     385  #
     386  #  If no block is given, an enumerator is returned instead.
     387  #
     388  #     "a8".upto("b6") {|s| print s, ' ' }
     389  #     for s in "a8".."b6"
     390  #       print s, ' '
     391  #     end
     392  #
     393  #  <em>produces:</em>
     394  #
     395  #     a8 a9 b0 b1 b2 b3 b4 b5 b6
     396  #     a8 a9 b0 b1 b2 b3 b4 b5 b6
     397  #
     398  #  If <i>str</i> and <i>other_str</i> contains only ascii numeric characters,
     399  #  both are recognized as decimal numbers. In addition, the width of
     400  #  string (e.g. leading zeros) is handled appropriately.
     401  #
     402  #     "9".upto("11").to_a   #=> ["9", "10", "11"]
     403  #     "25".upto("5").to_a   #=> []
     404  #     "07".upto("11").to_a  #=> ["07", "08", "09", "10", "11"]
     405  def upto(max, exclusive=false, &block)
     406    return to_enum(:upto, max, exclusive) unless block
     407    raise TypeError, "no implicit conversion of #{max.class} into String" unless max.kind_of? String
     408
     409    len = self.length
     410    maxlen = max.length
     411    # single character
     412    if len == 1 and maxlen == 1
     413      c = self.ord
     414      e = max.ord
     415      while c <= e
     416        break if exclusive and c == e
     417        yield c.chr(__ENCODING__)
     418        c += 1
     419      end
     420      return self
     421    end
     422    # both edges are all digits
     423    bi = self.to_i(10)
     424    ei = max.to_i(10)
     425    len = self.length
     426    if (bi > 0 or bi == "0"*len) and (ei > 0 or ei == "0"*maxlen)
     427      while bi <= ei
     428        break if exclusive and bi == ei
     429        s = bi.to_s
     430        s = s.rjust(len, "0") if s.length < len
     431        yield s
     432        bi += 1
     433      end
     434      return self
     435    end
     436    bs = self
     437    while true
     438      n = (bs <=> max)
     439      break if n > 0
     440      break if exclusive and n == 0
     441      yield bs
     442      break if n == 0
     443      bs = bs.succ
     444    end
     445    self
     446  end
    355447end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/src/string.c

    r331 r439  
    66#include <mruby/range.h>
    77
    8 static mrb_value
    9 mrb_str_getbyte(mrb_state *mrb, mrb_value str)
    10 {
    11   mrb_int pos;
    12   mrb_get_args(mrb, "i", &pos);
    13 
    14   if (pos < 0)
    15     pos += RSTRING_LEN(str);
    16   if (pos < 0 ||  RSTRING_LEN(str) <= pos)
    17     return mrb_nil_value();
    18 
    19   return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
    20 }
    21 
    22 static mrb_value
    23 mrb_str_setbyte(mrb_state *mrb, mrb_value str)
    24 {
    25   mrb_int pos, byte;
    26   long len;
    27 
    28   mrb_get_args(mrb, "ii", &pos, &byte);
    29 
    30   len = RSTRING_LEN(str);
    31   if (pos < -len || len <= pos)
    32     mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos));
    33   if (pos < 0)
    34     pos += len;
    35 
    36   mrb_str_modify(mrb, mrb_str_ptr(str));
    37   byte &= 0xff;
    38   RSTRING_PTR(str)[pos] = byte;
    39   return mrb_fixnum_value((unsigned char)byte);
    40 }
    41 
    42 static mrb_value
    43 mrb_str_byteslice(mrb_state *mrb, mrb_value str)
    44 {
    45   mrb_value a1;
     8#define ENC_ASCII_8BIT "ASCII-8BIT"
     9#define ENC_BINARY     "BINARY"
     10#define ENC_UTF8       "UTF-8"
     11
     12#define ENC_COMP_P(enc, enc_lit) \
     13  str_casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1)
     14
     15#ifdef MRB_WITHOUT_FLOAT
     16# define mrb_float_p(o) FALSE
     17#endif
     18
     19static mrb_bool
     20str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2)
     21{
     22  const char *e1, *e2;
     23
     24  if (len1 != len2) return FALSE;
     25  e1 = s1 + len1;
     26  e2 = s2 + len2;
     27  while (s1 < e1 && s2 < e2) {
     28    if (*s1 != *s2 && TOUPPER(*s1) != TOUPPER(*s2)) return FALSE;
     29    ++s1;
     30    ++s2;
     31  }
     32  return TRUE;
     33}
     34
     35static mrb_value
     36int_chr_binary(mrb_state *mrb, mrb_value num)
     37{
     38  mrb_int cp = mrb_int(mrb, num);
     39  char c;
     40  mrb_value str;
     41
     42  if (cp < 0 || 0xff < cp) {
     43    mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num);
     44  }
     45  c = (char)cp;
     46  str = mrb_str_new(mrb, &c, 1);
     47  RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
     48  return str;
     49}
     50
     51#ifdef MRB_UTF8_STRING
     52static mrb_value
     53int_chr_utf8(mrb_state *mrb, mrb_value num)
     54{
     55  mrb_int cp = mrb_int(mrb, num);
     56  char utf8[4];
    4657  mrb_int len;
    47   int argc;
    48 
    49   argc = mrb_get_args(mrb, "o|i", &a1, &len);
    50   if (argc == 2) {
    51     return mrb_str_substr(mrb, str, mrb_fixnum(a1), len);
    52   }
    53   switch (mrb_type(a1)) {
    54   case MRB_TT_RANGE:
    55     {
    56       mrb_int beg;
    57 
    58       len = RSTRING_LEN(str);
    59       switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) {
    60       case 0:                   /* not range */
    61         break;
    62       case 1:                   /* range */
    63         return mrb_str_substr(mrb, str, beg, len);
    64       case 2:                   /* out of range */
    65         mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1);
    66         break;
    67       }
    68       return mrb_nil_value();
    69     }
    70   case MRB_TT_FLOAT:
    71     a1 = mrb_fixnum_value((mrb_int)mrb_float(a1));
    72     /* fall through */
    73   case MRB_TT_FIXNUM:
    74     return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1);
    75   default:
    76     mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument");
    77   }
    78   /* not reached */
    79   return mrb_nil_value();
    80 }
     58  mrb_value str;
     59  uint32_t ascii_flag = 0;
     60
     61  if (cp < 0 || 0x10FFFF < cp) {
     62    mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num);
     63  }
     64  if (cp < 0x80) {
     65    utf8[0] = (char)cp;
     66    len = 1;
     67    ascii_flag = MRB_STR_ASCII;
     68  }
     69  else if (cp < 0x800) {
     70    utf8[0] = (char)(0xC0 | (cp >> 6));
     71    utf8[1] = (char)(0x80 | (cp & 0x3F));
     72    len = 2;
     73  }
     74  else if (cp < 0x10000) {
     75    utf8[0] = (char)(0xE0 |  (cp >> 12));
     76    utf8[1] = (char)(0x80 | ((cp >>  6) & 0x3F));
     77    utf8[2] = (char)(0x80 | ( cp        & 0x3F));
     78    len = 3;
     79  }
     80  else {
     81    utf8[0] = (char)(0xF0 |  (cp >> 18));
     82    utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
     83    utf8[2] = (char)(0x80 | ((cp >>  6) & 0x3F));
     84    utf8[3] = (char)(0x80 | ( cp        & 0x3F));
     85    len = 4;
     86  }
     87  str = mrb_str_new(mrb, utf8, len);
     88  mrb_str_ptr(str)->flags |= ascii_flag;
     89  return str;
     90}
     91#endif
    8192
    8293/*
     
    135146}
    136147
    137 static mrb_value mrb_fixnum_chr(mrb_state *mrb, mrb_value num);
    138 
    139148/*
    140149 *  call-seq:
     
    146155 *  Append---Concatenates the given object to <i>str</i>. If the object is a
    147156 *  <code>Integer</code>, it is considered as a codepoint, and is converted
    148  *  to a character before concatenation.
     157 *  to a character before concatenation
     158 *  (equivalent to <code>str.concat(integer.chr(__ENCODING__))</code>).
    149159 *
    150160 *     a = "hello "
     
    153163 */
    154164static mrb_value
    155 mrb_str_concat2(mrb_state *mrb, mrb_value self)
     165mrb_str_concat_m(mrb_state *mrb, mrb_value self)
    156166{
    157167  mrb_value str;
    158168
    159169  mrb_get_args(mrb, "o", &str);
    160   if (mrb_fixnum_p(str))
    161     str = mrb_fixnum_chr(mrb, str);
     170  if (mrb_fixnum_p(str) || mrb_float_p(str))
     171#ifdef MRB_UTF8_STRING
     172    str = int_chr_utf8(mrb, str);
     173#else
     174    str = int_chr_binary(mrb, str);
     175#endif
    162176  else
    163     str = mrb_string_type(mrb, str);
    164   mrb_str_concat(mrb, self, str);
     177    mrb_ensure_string_type(mrb, str);
     178  mrb_str_cat_str(mrb, self, str);
    165179  return self;
    166180}
     
    189203    size_t len_l, len_r;
    190204    int ai = mrb_gc_arena_save(mrb);
    191     sub = mrb_string_type(mrb, argv[i]);
     205    sub = mrb_ensure_string_type(mrb, argv[i]);
    192206    mrb_gc_arena_restore(mrb, ai);
    193207    len_l = RSTRING_LEN(self);
     
    218232    size_t len_l, len_r;
    219233    int ai = mrb_gc_arena_save(mrb);
    220     sub = mrb_string_type(mrb, argv[i]);
     234    sub = mrb_ensure_string_type(mrb, argv[i]);
    221235    mrb_gc_arena_restore(mrb, ai);
    222236    len_l = RSTRING_LEN(self);
     
    233247}
    234248
     249enum tr_pattern_type {
     250  TR_UNINITIALIZED = 0,
     251  TR_IN_ORDER  = 1,
     252  TR_RANGE = 2,
     253};
     254
     255/*
     256  #tr Pattern syntax
     257
     258  <syntax> ::= (<pattern>)* | '^' (<pattern>)*
     259  <pattern> ::= <in order> | <range>
     260  <in order> ::= (<ch>)+
     261  <range> ::= <ch> '-' <ch>
     262*/
     263struct tr_pattern {
     264  uint8_t type;         // 1:in-order, 2:range
     265  mrb_bool flag_reverse : 1;
     266  mrb_bool flag_on_heap : 1;
     267  uint16_t n;
     268  union {
     269    uint16_t start_pos;
     270    char ch[2];
     271  } val;
     272  struct tr_pattern *next;
     273};
     274
     275#define STATIC_TR_PATTERN { 0 }
     276
     277static inline void
     278tr_free_pattern(mrb_state *mrb, struct tr_pattern *pat)
     279{
     280  while (pat) {
     281    struct tr_pattern *p = pat->next;
     282    if (pat->flag_on_heap) {
     283      mrb_free(mrb, pat);
     284    }
     285    pat = p;
     286  }
     287}
     288
     289static struct tr_pattern*
     290tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_pattern, mrb_bool flag_reverse_enable)
     291{
     292  const char *pattern = RSTRING_PTR(v_pattern);
     293  mrb_int pattern_length = RSTRING_LEN(v_pattern);
     294  mrb_bool flag_reverse = FALSE;
     295  struct tr_pattern *pat1;
     296  mrb_int i = 0;
     297
     298  if(flag_reverse_enable && pattern_length >= 2 && pattern[0] == '^') {
     299    flag_reverse = TRUE;
     300    i++;
     301  }
     302
     303  while (i < pattern_length) {
     304    /* is range pattern ? */
     305    mrb_bool const ret_uninit = (ret->type == TR_UNINITIALIZED);
     306    pat1 = ret_uninit
     307           ? ret
     308           : (struct tr_pattern*)mrb_malloc_simple(mrb, sizeof(struct tr_pattern));
     309    if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') {
     310      if (pat1 == NULL && ret) {
     311      nomem:
     312        tr_free_pattern(mrb, ret);
     313        mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
     314        return NULL;            /* not reached */
     315      }
     316      pat1->type = TR_RANGE;
     317      pat1->flag_reverse = flag_reverse;
     318      pat1->flag_on_heap = !ret_uninit;
     319      pat1->n = pattern[i+2] - pattern[i] + 1;
     320      pat1->next = NULL;
     321      pat1->val.ch[0] = pattern[i];
     322      pat1->val.ch[1] = pattern[i+2];
     323      i += 3;
     324    }
     325    else {
     326      /* in order pattern. */
     327      mrb_int start_pos = i++;
     328      mrb_int len;
     329
     330      while (i < pattern_length) {
     331        if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-')
     332          break;
     333        i++;
     334      }
     335
     336      len = i - start_pos;
     337      if (len > UINT16_MAX) {
     338        mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65536)");
     339      }
     340      if (pat1 == NULL && ret) {
     341        goto nomem;
     342      }
     343      pat1->type = TR_IN_ORDER;
     344      pat1->flag_reverse = flag_reverse;
     345      pat1->flag_on_heap = !ret_uninit;
     346      pat1->n = len;
     347      pat1->next = NULL;
     348      pat1->val.start_pos = start_pos;
     349    }
     350
     351    if (ret == NULL || ret_uninit) {
     352      ret = pat1;
     353    }
     354    else {
     355      struct tr_pattern *p = ret;
     356      while (p->next != NULL) {
     357        p = p->next;
     358      }
     359      p->next = pat1;
     360    }
     361  }
     362
     363  return ret;
     364}
     365
     366static inline mrb_int
     367tr_find_character(const struct tr_pattern *pat, const char *pat_str, int ch)
     368{
     369  mrb_int ret = -1;
     370  mrb_int n_sum = 0;
     371  mrb_int flag_reverse = pat ? pat->flag_reverse : 0;
     372
     373  while (pat != NULL) {
     374    if (pat->type == TR_IN_ORDER) {
     375      int i;
     376      for (i = 0; i < pat->n; i++) {
     377        if (pat_str[pat->val.start_pos + i] == ch) ret = n_sum + i;
     378      }
     379    }
     380    else if (pat->type == TR_RANGE) {
     381      if (pat->val.ch[0] <= ch && ch <= pat->val.ch[1])
     382        ret = n_sum + ch - pat->val.ch[0];
     383    }
     384    else {
     385      mrb_assert(pat->type == TR_UNINITIALIZED);
     386    }
     387    n_sum += pat->n;
     388    pat = pat->next;
     389  }
     390
     391  if (flag_reverse) {
     392    return (ret < 0) ? MRB_INT_MAX : -1;
     393  }
     394  return ret;
     395}
     396
     397static inline mrb_int
     398tr_get_character(const struct tr_pattern *pat, const char *pat_str, mrb_int n_th)
     399{
     400  mrb_int n_sum = 0;
     401
     402  while (pat != NULL) {
     403    if (n_th < (n_sum + pat->n)) {
     404      mrb_int i = (n_th - n_sum);
     405
     406      switch (pat->type) {
     407      case TR_IN_ORDER:
     408        return pat_str[pat->val.start_pos + i];
     409      case TR_RANGE:
     410        return pat->val.ch[0]+i;
     411      case TR_UNINITIALIZED:
     412        return -1;
     413      }
     414    }
     415    if (pat->next == NULL) {
     416      switch (pat->type) {
     417      case TR_IN_ORDER:
     418        return pat_str[pat->val.start_pos + pat->n - 1];
     419      case TR_RANGE:
     420        return pat->val.ch[1];
     421      case TR_UNINITIALIZED:
     422        return -1;
     423      }
     424    }
     425    n_sum += pat->n;
     426    pat = pat->next;
     427  }
     428
     429  return -1;
     430}
     431
     432static inline void
     433tr_bitmap_set(uint8_t bitmap[32], uint8_t ch)
     434{
     435  uint8_t idx1 = ch / 8;
     436  uint8_t idx2 = ch % 8;
     437  bitmap[idx1] |= (1<<idx2);
     438}
     439
     440static inline mrb_bool
     441tr_bitmap_detect(uint8_t bitmap[32], uint8_t ch)
     442{
     443  uint8_t idx1 = ch / 8;
     444  uint8_t idx2 = ch % 8;
     445  if (bitmap[idx1] & (1<<idx2))
     446    return TRUE;
     447  return FALSE;
     448}
     449
     450/* compile patter to bitmap */
     451static void
     452tr_compile_pattern(const struct tr_pattern *pat, mrb_value pstr, uint8_t bitmap[32])
     453{
     454  const char *pattern = RSTRING_PTR(pstr);
     455  mrb_int flag_reverse = pat ? pat->flag_reverse : 0;
     456  int i;
     457
     458  for (i=0; i<32; i++) {
     459    bitmap[i] = 0;
     460  }
     461  while (pat != NULL) {
     462    if (pat->type == TR_IN_ORDER) {
     463      for (i = 0; i < pat->n; i++) {
     464        tr_bitmap_set(bitmap, pattern[pat->val.start_pos + i]);
     465      }
     466    }
     467    else if (pat->type == TR_RANGE) {
     468      for (i = pat->val.ch[0]; i < pat->val.ch[1]; i++) {
     469        tr_bitmap_set(bitmap, i);
     470      }
     471    }
     472    else {
     473      mrb_assert(pat->type == TR_UNINITIALIZED);
     474    }
     475    pat = pat->next;
     476  }
     477
     478  if (flag_reverse) {
     479    for (i=0; i<32; i++) {
     480      bitmap[i] ^= 0xff;
     481    }
     482  }
     483}
     484
     485static mrb_bool
     486str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squeeze)
     487{
     488  struct tr_pattern pat = STATIC_TR_PATTERN;
     489  struct tr_pattern rep_storage = STATIC_TR_PATTERN;
     490  char *s;
     491  mrb_int len;
     492  mrb_int i;
     493  mrb_int j;
     494  mrb_bool flag_changed = FALSE;
     495  mrb_int lastch = -1;
     496  struct tr_pattern *rep;
     497
     498  mrb_str_modify(mrb, mrb_str_ptr(str));
     499  tr_parse_pattern(mrb, &pat, p1, TRUE);
     500  rep = tr_parse_pattern(mrb, &rep_storage, p2, FALSE);
     501  s = RSTRING_PTR(str);
     502  len = RSTRING_LEN(str);
     503
     504  for (i=j=0; i<len; i++,j++) {
     505    mrb_int n = tr_find_character(&pat, RSTRING_PTR(p1), s[i]);
     506
     507    if (i>j) s[j] = s[i];
     508    if (n >= 0) {
     509      flag_changed = TRUE;
     510      if (rep == NULL) {
     511        j--;
     512      }
     513      else {
     514        mrb_int c = tr_get_character(rep, RSTRING_PTR(p2), n);
     515
     516        if (c < 0 || (squeeze && c == lastch)) {
     517          j--;
     518          continue;
     519        }
     520        if (c > 0x80) {
     521          mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c);
     522        }
     523        lastch = c;
     524        s[i] = (char)c;
     525      }
     526    }
     527  }
     528
     529  tr_free_pattern(mrb, &pat);
     530  tr_free_pattern(mrb, rep);
     531
     532  if (flag_changed) {
     533    RSTR_SET_LEN(RSTRING(str), j);
     534    RSTRING_PTR(str)[j] = 0;
     535  }
     536  return flag_changed;
     537}
     538
     539/*
     540 * call-seq:
     541 *   str.tr(from_str, to_str)   => new_str
     542 *
     543 * Returns a copy of str with the characters in from_str replaced by the
     544 * corresponding characters in to_str.  If to_str is shorter than from_str,
     545 * it is padded with its last character in order to maintain the
     546 * correspondence.
     547 *
     548 *  "hello".tr('el', 'ip')      #=> "hippo"
     549 *  "hello".tr('aeiou', '*')    #=> "h*ll*"
     550 *  "hello".tr('aeiou', 'AA*')  #=> "hAll*"
     551 *
     552 * Both strings may use the c1-c2 notation to denote ranges of characters,
     553 * and from_str may start with a ^, which denotes all characters except
     554 * those listed.
     555 *
     556 *  "hello".tr('a-y', 'b-z')    #=> "ifmmp"
     557 *  "hello".tr('^aeiou', '*')   #=> "*e**o"
     558 *
     559 * The backslash character \ can be used to escape ^ or - and is otherwise
     560 * ignored unless it appears at the end of a range or the end of the
     561 * from_str or to_str:
     562 *
     563 *
     564 *  "hello^world".tr("\\^aeiou", "*") #=> "h*ll**w*rld"
     565 *  "hello-world".tr("a\\-eo", "*")   #=> "h*ll**w*rld"
     566 *
     567 *  "hello\r\nworld".tr("\r", "")   #=> "hello\nworld"
     568 *  "hello\r\nworld".tr("\\r", "")  #=> "hello\r\nwold"
     569 *  "hello\r\nworld".tr("\\\r", "") #=> "hello\nworld"
     570 *
     571 *  "X['\\b']".tr("X\\", "")   #=> "['b']"
     572 *  "X['\\b']".tr("X-\\]", "") #=> "'b'"
     573 *
     574 *  Note: conversion is effective only in ASCII region.
     575 */
     576static mrb_value
     577mrb_str_tr(mrb_state *mrb, mrb_value str)
     578{
     579  mrb_value dup;
     580  mrb_value p1, p2;
     581
     582  mrb_get_args(mrb, "SS", &p1, &p2);
     583  dup = mrb_str_dup(mrb, str);
     584  str_tr(mrb, dup, p1, p2, FALSE);
     585  return dup;
     586}
     587
     588/*
     589 * call-seq:
     590 *   str.tr!(from_str, to_str)   -> str or nil
     591 *
     592 * Translates str in place, using the same rules as String#tr.
     593 * Returns str, or nil if no changes were made.
     594 */
     595static mrb_value
     596mrb_str_tr_bang(mrb_state *mrb, mrb_value str)
     597{
     598  mrb_value p1, p2;
     599
     600  mrb_get_args(mrb, "SS", &p1, &p2);
     601  if (str_tr(mrb, str, p1, p2, FALSE)) {
     602    return str;
     603  }
     604  return mrb_nil_value();
     605}
     606
     607/*
     608 * call-seq:
     609 *   str.tr_s(from_str, to_str)   -> new_str
     610 *
     611 * Processes a copy of str as described under String#tr, then removes
     612 * duplicate characters in regions that were affected by the translation.
     613 *
     614 *  "hello".tr_s('l', 'r')     #=> "hero"
     615 *  "hello".tr_s('el', '*')    #=> "h*o"
     616 *  "hello".tr_s('el', 'hx')   #=> "hhxo"
     617 */
     618static mrb_value
     619mrb_str_tr_s(mrb_state *mrb, mrb_value str)
     620{
     621  mrb_value dup;
     622  mrb_value p1, p2;
     623
     624  mrb_get_args(mrb, "SS", &p1, &p2);
     625  dup = mrb_str_dup(mrb, str);
     626  str_tr(mrb, dup, p1, p2, TRUE);
     627  return dup;
     628}
     629
     630/*
     631 * call-seq:
     632 *   str.tr_s!(from_str, to_str)   -> str or nil
     633 *
     634 * Performs String#tr_s processing on str in place, returning
     635 * str, or nil if no changes were made.
     636 */
     637static mrb_value
     638mrb_str_tr_s_bang(mrb_state *mrb, mrb_value str)
     639{
     640  mrb_value p1, p2;
     641
     642  mrb_get_args(mrb, "SS", &p1, &p2);
     643  if (str_tr(mrb, str, p1, p2, TRUE)) {
     644    return str;
     645  }
     646  return mrb_nil_value();
     647}
     648
     649static mrb_bool
     650str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat)
     651{
     652  struct tr_pattern pat_storage = STATIC_TR_PATTERN;
     653  struct tr_pattern *pat = NULL;
     654  mrb_int i, j;
     655  char *s;
     656  mrb_int len;
     657  mrb_bool flag_changed = FALSE;
     658  mrb_int lastch = -1;
     659  uint8_t bitmap[32];
     660
     661  mrb_str_modify(mrb, mrb_str_ptr(str));
     662  if (!mrb_nil_p(v_pat)) {
     663    pat = tr_parse_pattern(mrb, &pat_storage, v_pat, TRUE);
     664    tr_compile_pattern(pat, v_pat, bitmap);
     665    tr_free_pattern(mrb, pat);
     666  }
     667  s = RSTRING_PTR(str);
     668  len = RSTRING_LEN(str);
     669
     670  if (pat) {
     671    for (i=j=0; i<len; i++,j++) {
     672      if (i>j) s[j] = s[i];
     673      if (tr_bitmap_detect(bitmap, s[i]) && s[i] == lastch) {
     674        flag_changed = TRUE;
     675        j--;
     676      }
     677      lastch = s[i];
     678    }
     679  }
     680  else {
     681    for (i=j=0; i<len; i++,j++) {
     682      if (i>j) s[j] = s[i];
     683      if (s[i] >= 0 && s[i] == lastch) {
     684        flag_changed = TRUE;
     685        j--;
     686      }
     687      lastch = s[i];
     688    }
     689  }
     690
     691  if (flag_changed) {
     692    RSTR_SET_LEN(RSTRING(str), j);
     693    RSTRING_PTR(str)[j] = 0;
     694  }
     695  return flag_changed;
     696}
     697
     698/*
     699 * call-seq:
     700 *   str.squeeze([other_str])    -> new_str
     701 *
     702 * Builds a set of characters from the other_str
     703 * parameter(s) using the procedure described for String#count. Returns a
     704 * new string where runs of the same character that occur in this set are
     705 * replaced by a single character. If no arguments are given, all runs of
     706 * identical characters are replaced by a single character.
     707 *
     708 *  "yellow moon".squeeze                  #=> "yelow mon"
     709 *  "  now   is  the".squeeze(" ")         #=> " now is the"
     710 *  "putters shoot balls".squeeze("m-z")   #=> "puters shot balls"
     711 */
     712static mrb_value
     713mrb_str_squeeze(mrb_state *mrb, mrb_value str)
     714{
     715  mrb_value pat = mrb_nil_value();
     716  mrb_value dup;
     717
     718  mrb_get_args(mrb, "|S", &pat);
     719  dup = mrb_str_dup(mrb, str);
     720  str_squeeze(mrb, dup, pat);
     721  return dup;
     722}
     723
     724/*
     725 * call-seq:
     726 *   str.squeeze!([other_str])   -> str or nil
     727 *
     728 * Squeezes str in place, returning either str, or nil if no
     729 * changes were made.
     730 */
     731static mrb_value
     732mrb_str_squeeze_bang(mrb_state *mrb, mrb_value str)
     733{
     734  mrb_value pat = mrb_nil_value();
     735
     736  mrb_get_args(mrb, "|S", &pat);
     737  if (str_squeeze(mrb, str, pat)) {
     738    return str;
     739  }
     740  return mrb_nil_value();
     741}
     742
     743static mrb_bool
     744str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat)
     745{
     746  struct tr_pattern pat = STATIC_TR_PATTERN;
     747  mrb_int i, j;
     748  char *s;
     749  mrb_int len;
     750  mrb_bool flag_changed = FALSE;
     751  uint8_t bitmap[32];
     752
     753  mrb_str_modify(mrb, mrb_str_ptr(str));
     754  tr_parse_pattern(mrb, &pat, v_pat, TRUE);
     755  tr_compile_pattern(&pat, v_pat, bitmap);
     756  tr_free_pattern(mrb, &pat);
     757
     758  s = RSTRING_PTR(str);
     759  len = RSTRING_LEN(str);
     760
     761  for (i=j=0; i<len; i++,j++) {
     762    if (i>j) s[j] = s[i];
     763    if (tr_bitmap_detect(bitmap, s[i])) {
     764      flag_changed = TRUE;
     765      j--;
     766    }
     767  }
     768  if (flag_changed) {
     769    RSTR_SET_LEN(RSTRING(str), j);
     770    RSTRING_PTR(str)[j] = 0;
     771  }
     772  return flag_changed;
     773}
     774
     775static mrb_value
     776mrb_str_delete(mrb_state *mrb, mrb_value str)
     777{
     778  mrb_value pat;
     779  mrb_value dup;
     780
     781  mrb_get_args(mrb, "S", &pat);
     782  dup = mrb_str_dup(mrb, str);
     783  str_delete(mrb, dup, pat);
     784  return dup;
     785}
     786
     787static mrb_value
     788mrb_str_delete_bang(mrb_state *mrb, mrb_value str)
     789{
     790  mrb_value pat;
     791
     792  mrb_get_args(mrb, "S", &pat);
     793  if (str_delete(mrb, str, pat)) {
     794    return str;
     795  }
     796  return mrb_nil_value();
     797}
     798
     799/*
     800 * call_seq:
     801 *   str.count([other_str])   -> integer
     802 *
     803 * Each other_str parameter defines a set of characters to count.  The
     804 * intersection of these sets defines the characters to count in str.  Any
     805 * other_str that starts with a caret ^ is negated.  The sequence c1-c2
     806 * means all characters between c1 and c2.  The backslash character \ can
     807 * be used to escape ^ or - and is otherwise ignored unless it appears at
     808 * the end of a sequence or the end of a other_str.
     809 */
     810static mrb_value
     811mrb_str_count(mrb_state *mrb, mrb_value str)
     812{
     813  mrb_value v_pat = mrb_nil_value();
     814  mrb_int i;
     815  char *s;
     816  mrb_int len;
     817  mrb_int count = 0;
     818  struct tr_pattern pat = STATIC_TR_PATTERN;
     819  uint8_t bitmap[32];
     820
     821  mrb_get_args(mrb, "S", &v_pat);
     822  tr_parse_pattern(mrb, &pat, v_pat, TRUE);
     823  tr_compile_pattern(&pat, v_pat, bitmap);
     824  tr_free_pattern(mrb, &pat);
     825
     826  s = RSTRING_PTR(str);
     827  len = RSTRING_LEN(str);
     828  for (i = 0; i < len; i++) {
     829    if (tr_bitmap_detect(bitmap, s[i])) count++;
     830  }
     831  return mrb_fixnum_value(count);
     832}
     833
    235834static mrb_value
    236835mrb_str_hex(mrb_state *mrb, mrb_value self)
     
    260859}
    261860
    262 static mrb_value
    263 mrb_fixnum_chr(mrb_state *mrb, mrb_value num)
    264 {
    265   mrb_int cp = mrb_fixnum(num);
     861/*
     862 *  call-seq:
     863 *     int.chr([encoding])  ->  string
     864 *
     865 *  Returns a string containing the character represented by the +int+'s value
     866 *  according to +encoding+. +"ASCII-8BIT"+ (+"BINARY"+) and +"UTF-8"+ (only
     867 *  with +MRB_UTF8_STRING+) can be specified as +encoding+ (default is
     868 *  +"ASCII-8BIT"+).
     869 *
     870 *     65.chr                  #=> "A"
     871 *     230.chr                 #=> "\xE6"
     872 *     230.chr("ASCII-8BIT")   #=> "\xE6"
     873 *     230.chr("UTF-8")        #=> "\u00E6"
     874 */
     875static mrb_value
     876mrb_int_chr(mrb_state *mrb, mrb_value num)
     877{
     878  mrb_value enc;
     879  mrb_bool enc_given;
     880
     881  mrb_get_args(mrb, "|S?", &enc, &enc_given);
     882  if (!enc_given ||
     883      ENC_COMP_P(enc, ENC_ASCII_8BIT) ||
     884      ENC_COMP_P(enc, ENC_BINARY)) {
     885    return int_chr_binary(mrb, num);
     886  }
    266887#ifdef MRB_UTF8_STRING
    267   char utf8[4];
    268   mrb_int len;
    269 
    270   if (cp < 0 || 0x10FFFF < cp) {
    271     mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num);
    272   }
    273   if (cp < 0x80) {
    274     utf8[0] = (char)cp;
    275     len = 1;
    276   }
    277   else if (cp < 0x800) {
    278     utf8[0] = (char)(0xC0 | (cp >> 6));
    279     utf8[1] = (char)(0x80 | (cp & 0x3F));
    280     len = 2;
    281   }
    282   else if (cp < 0x10000) {
    283     utf8[0] = (char)(0xE0 |  (cp >> 12));
    284     utf8[1] = (char)(0x80 | ((cp >>  6) & 0x3F));
    285     utf8[2] = (char)(0x80 | ( cp        & 0x3F));
    286     len = 3;
    287   }
     888  else if (ENC_COMP_P(enc, ENC_UTF8)) {
     889    return int_chr_utf8(mrb, num);
     890  }
     891#endif
    288892  else {
    289     utf8[0] = (char)(0xF0 |  (cp >> 18));
    290     utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
    291     utf8[2] = (char)(0x80 | ((cp >>  6) & 0x3F));
    292     utf8[3] = (char)(0x80 | ( cp        & 0x3F));
    293     len = 4;
    294   }
    295   return mrb_str_new(mrb, utf8, len);
    296 #else
    297   char c;
    298 
    299   if (cp < 0 || 0xff < cp) {
    300     mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num);
    301   }
    302   c = (char)cp;
    303   return mrb_str_new(mrb, &c, 1);
    304 #endif
    305 }
    306 
    307 /*
    308  *  call-seq:
    309  *     string.lines    ->  array of string
    310  *
    311  *  Returns strings per line;
    312  *
    313  *     a = "abc\ndef"
    314  *     a.lines    #=> ["abc\n", "def"]
    315  */
    316 static mrb_value
    317 mrb_str_lines(mrb_state *mrb, mrb_value self)
    318 {
    319   mrb_value result;
    320   mrb_value blk;
    321   int ai;
    322   mrb_int len;
    323   mrb_value arg;
    324   char *b = RSTRING_PTR(self);
    325   char *p = b, *t;
    326   char *e = b + RSTRING_LEN(self);
    327 
    328   mrb_get_args(mrb, "&", &blk);
    329 
    330   result = mrb_ary_new(mrb);
    331   ai = mrb_gc_arena_save(mrb);
    332   if (!mrb_nil_p(blk)) {
    333     while (p < e) {
    334       t = p;
    335       while (p < e && *p != '\n') p++;
    336       if (*p == '\n') p++;
    337       len = (mrb_int) (p - t);
    338       arg = mrb_str_new(mrb, t, len);
    339       mrb_yield_argv(mrb, blk, 1, &arg);
    340       mrb_gc_arena_restore(mrb, ai);
    341       if (b != RSTRING_PTR(self)) {
    342         ptrdiff_t diff = p - b;
    343         b = RSTRING_PTR(self);
    344         p = b + diff;
    345       }
    346       e = b + RSTRING_LEN(self);
    347     }
    348     return self;
    349   }
    350   while (p < e) {
    351     t = p;
    352     while (p < e && *p != '\n') p++;
    353     if (*p == '\n') p++;
    354     len = (mrb_int) (p - t);
    355     mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len));
    356     mrb_gc_arena_restore(mrb, ai);
    357   }
    358   return result;
     893    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown encoding name - %v", enc);
     894  }
     895  /* not reached */
     896  return mrb_nil_value();
    359897}
    360898
     
    5221060#endif
    5231061
    524 static mrb_bool
    525 all_digits_p(const char *s, mrb_int len)
    526 {
    527   while (len-- > 0) {
    528     if (!ISDIGIT(*s)) return FALSE;
    529     s++;
    530   }
    531   return TRUE;
    532 }
    533 
    5341062/*
    5351063 *  call-seq:
    536  *     str.upto(other_str, exclusive=false) {|s| block }   -> str
    537  *     str.upto(other_str, exclusive=false)                -> an_enumerator
    538  *
    539  *  Iterates through successive values, starting at <i>str</i> and
    540  *  ending at <i>other_str</i> inclusive, passing each value in turn to
    541  *  the block. The <code>String#succ</code> method is used to generate
    542  *  each value.  If optional second argument exclusive is omitted or is false,
    543  *  the last value will be included; otherwise it will be excluded.
    544  *
    545  *  If no block is given, an enumerator is returned instead.
    546  *
    547  *     "a8".upto("b6") {|s| print s, ' ' }
    548  *     for s in "a8".."b6"
    549  *       print s, ' '
    550  *     end
    551  *
    552  *  <em>produces:</em>
    553  *
    554  *     a8 a9 b0 b1 b2 b3 b4 b5 b6
    555  *     a8 a9 b0 b1 b2 b3 b4 b5 b6
    556  *
    557  *  If <i>str</i> and <i>other_str</i> contains only ascii numeric characters,
    558  *  both are recognized as decimal numbers. In addition, the width of
    559  *  string (e.g. leading zeros) is handled appropriately.
    560  *
    561  *     "9".upto("11").to_a   #=> ["9", "10", "11"]
    562  *     "25".upto("5").to_a   #=> []
    563  *     "07".upto("11").to_a  #=> ["07", "08", "09", "10", "11"]
    564  */
    565 static mrb_value
    566 mrb_str_upto(mrb_state *mrb, mrb_value beg)
    567 {
    568   mrb_value end;
    569   mrb_value exclusive = mrb_false_value();
    570   mrb_value block = mrb_nil_value();
    571   mrb_value current, after_end;
    572   mrb_int n;
    573   mrb_bool excl;
    574 
    575   mrb_get_args(mrb, "o|o&", &end, &exclusive, &block);
    576 
    577   if (mrb_nil_p(block)) {
    578     return mrb_funcall(mrb, beg, "to_enum", 3, mrb_symbol_value(mrb_intern_lit(mrb, "upto")), end, exclusive);
    579   }
    580   end = mrb_string_type(mrb, end);
    581   excl = mrb_test(exclusive);
    582 
    583   /* single character */
    584   if (RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1 &&
    585   ISASCII(RSTRING_PTR(beg)[0]) && ISASCII(RSTRING_PTR(end)[0])) {
    586     char c = RSTRING_PTR(beg)[0];
    587     char e = RSTRING_PTR(end)[0];
    588     int ai = mrb_gc_arena_save(mrb);
    589 
    590     if (c > e || (excl && c == e)) return beg;
    591     for (;;) {
    592       mrb_yield(mrb, block, mrb_str_new(mrb, &c, 1));
    593       mrb_gc_arena_restore(mrb, ai);
    594       if (!excl && c == e) break;
    595       c++;
    596       if (excl && c == e) break;
    597     }
    598     return beg;
    599   }
    600   /* both edges are all digits */
    601   if (ISDIGIT(RSTRING_PTR(beg)[0]) && ISDIGIT(RSTRING_PTR(end)[0]) &&
    602       all_digits_p(RSTRING_PTR(beg), RSTRING_LEN(beg)) &&
    603       all_digits_p(RSTRING_PTR(end), RSTRING_LEN(end))) {
    604     int ai = mrb_gc_arena_save(mrb);
    605     mrb_int min_width = RSTRING_LEN(beg);
    606     mrb_int max_width = RSTRING_LEN(end);
    607     mrb_int bi = mrb_int(mrb, mrb_str_to_inum(mrb, beg, 10, FALSE));
    608     mrb_int ei = mrb_int(mrb, mrb_str_to_inum(mrb, end, 10, FALSE));
    609     mrb_value str = mrb_str_new(mrb, NULL, max_width);
    610     char *buf = RSTRING_PTR(str);
    611 
    612     while (bi <= ei) {
    613       if (excl && bi == ei) break;
    614       snprintf(buf, max_width+1, "%.*" MRB_PRId, (int)min_width, bi);
    615       mrb_yield(mrb, block, mrb_str_new(mrb, buf, strlen(buf)));
    616       mrb_gc_arena_restore(mrb, ai);
    617       bi++;
    618     }
    619 
    620     return beg;
    621   }
    622   /* normal case */
    623   n = mrb_int(mrb, mrb_funcall(mrb, beg, "<=>", 1, end));
    624   if (n > 0 || (excl && n == 0)) return beg;
    625 
    626   after_end = mrb_funcall(mrb, end, "succ", 0);
    627   current = mrb_str_dup(mrb, beg);
    628   while (!mrb_str_equal(mrb, current, after_end)) {
    629     int ai = mrb_gc_arena_save(mrb);
    630     mrb_value next = mrb_nil_value();
    631     if (excl || !mrb_str_equal(mrb, current, end))
    632       next = mrb_funcall(mrb, current, "succ", 0);
    633     mrb_yield(mrb, block, current);
    634     if (mrb_nil_p(next)) break;
    635     current = mrb_str_to_str(mrb, next);
    636     if (excl && mrb_str_equal(mrb, current, end)) break;
    637     if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0)
    638       break;
     1064 *     str.delete_prefix!(prefix) -> self or nil
     1065 *
     1066 *  Deletes leading <code>prefix</code> from <i>str</i>, returning
     1067 *  <code>nil</code> if no change was made.
     1068 *
     1069 *     "hello".delete_prefix!("hel") #=> "lo"
     1070 *     "hello".delete_prefix!("llo") #=> nil
     1071 */
     1072static mrb_value
     1073mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self)
     1074{
     1075  mrb_int plen, slen;
     1076  char *ptr, *s;
     1077  struct RString *str = RSTRING(self);
     1078
     1079  mrb_get_args(mrb, "s", &ptr, &plen);
     1080  slen = RSTR_LEN(str);
     1081  if (plen > slen) return mrb_nil_value();
     1082  s = RSTR_PTR(str);
     1083  if (memcmp(s, ptr, plen) != 0) return mrb_nil_value();
     1084  if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
     1085    str->as.heap.ptr += plen;
     1086  }
     1087  else {
     1088    mrb_str_modify(mrb, str);
     1089    s = RSTR_PTR(str);
     1090    memmove(s, s+plen, slen-plen);
     1091  }
     1092  RSTR_SET_LEN(str, slen-plen);
     1093  return self;
     1094}
     1095
     1096/*
     1097 *  call-seq:
     1098 *     str.delete_prefix(prefix) -> new_str
     1099 *
     1100 *  Returns a copy of <i>str</i> with leading <code>prefix</code> deleted.
     1101 *
     1102 *     "hello".delete_prefix("hel") #=> "lo"
     1103 *     "hello".delete_prefix("llo") #=> "hello"
     1104 */
     1105static mrb_value
     1106mrb_str_del_prefix(mrb_state *mrb, mrb_value self)
     1107{
     1108  mrb_int plen, slen;
     1109  char *ptr;
     1110
     1111  mrb_get_args(mrb, "s", &ptr, &plen);
     1112  slen = RSTRING_LEN(self);
     1113  if (plen > slen) return mrb_str_dup(mrb, self);
     1114  if (memcmp(RSTRING_PTR(self), ptr, plen) != 0)
     1115    return mrb_str_dup(mrb, self);
     1116  return mrb_str_substr(mrb, self, plen, slen-plen);
     1117}
     1118
     1119/*
     1120 *  call-seq:
     1121 *     str.delete_suffix!(suffix) -> self or nil
     1122 *
     1123 *  Deletes trailing <code>suffix</code> from <i>str</i>, returning
     1124 *  <code>nil</code> if no change was made.
     1125 *
     1126 *     "hello".delete_suffix!("llo") #=> "he"
     1127 *     "hello".delete_suffix!("hel") #=> nil
     1128 */
     1129static mrb_value
     1130mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self)
     1131{
     1132  mrb_int plen, slen;
     1133  char *ptr, *s;
     1134  struct RString *str = RSTRING(self);
     1135
     1136  mrb_get_args(mrb, "s", &ptr, &plen);
     1137  slen = RSTR_LEN(str);
     1138  if (plen > slen) return mrb_nil_value();
     1139  s = RSTR_PTR(str);
     1140  if (memcmp(s+slen-plen, ptr, plen) != 0) return mrb_nil_value();
     1141  if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
     1142    /* no need to modify string */
     1143  }
     1144  else {
     1145    mrb_str_modify(mrb, str);
     1146  }
     1147  RSTR_SET_LEN(str, slen-plen);
     1148  return self;
     1149}
     1150
     1151/*
     1152 *  call-seq:
     1153 *     str.delete_suffix(suffix) -> new_str
     1154 *
     1155 *  Returns a copy of <i>str</i> with leading <code>suffix</code> deleted.
     1156 *
     1157 *     "hello".delete_suffix("hel") #=> "lo"
     1158 *     "hello".delete_suffix("llo") #=> "hello"
     1159 */
     1160static mrb_value
     1161mrb_str_del_suffix(mrb_state *mrb, mrb_value self)
     1162{
     1163  mrb_int plen, slen;
     1164  char *ptr;
     1165
     1166  mrb_get_args(mrb, "s", &ptr, &plen);
     1167  slen = RSTRING_LEN(self);
     1168  if (plen > slen) return mrb_str_dup(mrb, self);
     1169  if (memcmp(RSTRING_PTR(self)+slen-plen, ptr, plen) != 0)
     1170    return mrb_str_dup(mrb, self);
     1171  return mrb_str_substr(mrb, self, 0, slen-plen);
     1172}
     1173
     1174static mrb_value
     1175mrb_str_lines(mrb_state *mrb, mrb_value self)
     1176{
     1177  mrb_value result;
     1178  int ai;
     1179  mrb_int len;
     1180  char *b = RSTRING_PTR(self);
     1181  char *p = b, *t;
     1182  char *e = b + RSTRING_LEN(self);
     1183
     1184  result = mrb_ary_new(mrb);
     1185  ai = mrb_gc_arena_save(mrb);
     1186  while (p < e) {
     1187    t = p;
     1188    while (p < e && *p != '\n') p++;
     1189    if (*p == '\n') p++;
     1190    len = (mrb_int) (p - t);
     1191    mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len));
    6391192    mrb_gc_arena_restore(mrb, ai);
    6401193  }
    641 
    642   return beg;
     1194  return result;
    6431195}
    6441196
     
    6491201
    6501202  mrb_define_method(mrb, s, "dump",            mrb_str_dump,            MRB_ARGS_NONE());
    651   mrb_define_method(mrb, s, "getbyte",         mrb_str_getbyte,         MRB_ARGS_REQ(1));
    652   mrb_define_method(mrb, s, "setbyte",         mrb_str_setbyte,         MRB_ARGS_REQ(2));
    653   mrb_define_method(mrb, s, "byteslice",       mrb_str_byteslice,       MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
    6541203  mrb_define_method(mrb, s, "swapcase!",       mrb_str_swapcase_bang,   MRB_ARGS_NONE());
    6551204  mrb_define_method(mrb, s, "swapcase",        mrb_str_swapcase,        MRB_ARGS_NONE());
    656   mrb_define_method(mrb, s, "concat",          mrb_str_concat2,         MRB_ARGS_REQ(1));
    657   mrb_define_method(mrb, s, "<<",              mrb_str_concat2,         MRB_ARGS_REQ(1));
     1205  mrb_define_method(mrb, s, "concat",          mrb_str_concat_m,        MRB_ARGS_REQ(1));
     1206  mrb_define_method(mrb, s, "<<",              mrb_str_concat_m,        MRB_ARGS_REQ(1));
     1207  mrb_define_method(mrb, s, "count",           mrb_str_count,           MRB_ARGS_REQ(1));
     1208  mrb_define_method(mrb, s, "tr",              mrb_str_tr,              MRB_ARGS_REQ(2));
     1209  mrb_define_method(mrb, s, "tr!",             mrb_str_tr_bang,         MRB_ARGS_REQ(2));
     1210  mrb_define_method(mrb, s, "tr_s",            mrb_str_tr_s,            MRB_ARGS_REQ(2));
     1211  mrb_define_method(mrb, s, "tr_s!",           mrb_str_tr_s_bang,       MRB_ARGS_REQ(2));
     1212  mrb_define_method(mrb, s, "squeeze",         mrb_str_squeeze,         MRB_ARGS_OPT(1));
     1213  mrb_define_method(mrb, s, "squeeze!",        mrb_str_squeeze_bang,    MRB_ARGS_OPT(1));
     1214  mrb_define_method(mrb, s, "delete",          mrb_str_delete,          MRB_ARGS_REQ(1));
     1215  mrb_define_method(mrb, s, "delete!",         mrb_str_delete_bang,     MRB_ARGS_REQ(1));
    6581216  mrb_define_method(mrb, s, "start_with?",     mrb_str_start_with,      MRB_ARGS_REST());
    6591217  mrb_define_method(mrb, s, "end_with?",       mrb_str_end_with,        MRB_ARGS_REST());
     
    6611219  mrb_define_method(mrb, s, "oct",             mrb_str_oct,             MRB_ARGS_NONE());
    6621220  mrb_define_method(mrb, s, "chr",             mrb_str_chr,             MRB_ARGS_NONE());
    663   mrb_define_method(mrb, s, "lines",           mrb_str_lines,           MRB_ARGS_NONE());
    6641221  mrb_define_method(mrb, s, "succ",            mrb_str_succ,            MRB_ARGS_NONE());
    6651222  mrb_define_method(mrb, s, "succ!",           mrb_str_succ_bang,       MRB_ARGS_NONE());
    666   mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ"));
    667   mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!"));
    668   mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE());
    669   mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY());
    670 
    671   mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
     1223  mrb_define_method(mrb, s, "next",            mrb_str_succ,            MRB_ARGS_NONE());
     1224  mrb_define_method(mrb, s, "next!",           mrb_str_succ_bang,       MRB_ARGS_NONE());
     1225  mrb_define_method(mrb, s, "ord",             mrb_str_ord,             MRB_ARGS_NONE());
     1226  mrb_define_method(mrb, s, "delete_prefix!",  mrb_str_del_prefix_bang, MRB_ARGS_REQ(1));
     1227  mrb_define_method(mrb, s, "delete_prefix",   mrb_str_del_prefix,      MRB_ARGS_REQ(1));
     1228  mrb_define_method(mrb, s, "delete_suffix!",  mrb_str_del_suffix_bang, MRB_ARGS_REQ(1));
     1229  mrb_define_method(mrb, s, "delete_suffix",   mrb_str_del_suffix,      MRB_ARGS_REQ(1));
     1230
     1231  mrb_define_method(mrb, s, "__lines",         mrb_str_lines,           MRB_ARGS_NONE());
     1232
     1233  mrb_define_method(mrb, mrb_module_get(mrb, "Integral"), "chr", mrb_int_chr, MRB_ARGS_OPT(1));
    6721234}
    6731235
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/test/string.rb

    r331 r439  
     1# coding: utf-8
    12##
    23# String(Ext) Test
    34
    4 UTF8STRING = ("\343\201\202".size == 1)
    5 
    6 assert('String.try_convert') do
    7   assert_nil String.try_convert(nil)
    8   assert_nil String.try_convert(:foo)
    9   assert_equal "", String.try_convert("")
    10   assert_equal "1,2,3", String.try_convert("1,2,3")
    11 end
    12 
    13 assert('String#getbyte') do
    14   str1 = "hello"
    15   bytes1 = [104, 101, 108, 108, 111]
    16   assert_equal bytes1[0], str1.getbyte(0)
    17   assert_equal bytes1[-1], str1.getbyte(-1)
    18   assert_equal bytes1[6], str1.getbyte(6)
    19 
    20   str2 = "\xFF"
    21   bytes2 = [0xFF]
    22   assert_equal bytes2[0], str2.getbyte(0)
    23 end
    24 
    25 assert('String#setbyte') do
    26   str1 = "hello"
    27   h = "H".getbyte(0)
    28   str1.setbyte(0, h)
    29   assert_equal(h, str1.getbyte(0))
    30   assert_equal("Hello", str1)
    31 end
    32 
    33 assert("String#setbyte raises IndexError if arg conversion resizes String") do
    34   $s = "01234\n"
    35   class Tmp
    36       def to_i
    37           $s.chomp! ''
    38           95
    39       end
    40   end
    41   tmp = Tmp.new
    42   assert_raise(IndexError) { $s.setbyte(5, tmp) }
    43 end
    44 
    45 assert('String#byteslice') do
    46   str1 = "hello"
    47   assert_equal("e", str1.byteslice(1))
    48   assert_equal("o", str1.byteslice(-1))
    49   assert_equal("ell", str1.byteslice(1..3))
    50   assert_equal("el", str1.byteslice(1...3))
     5UTF8STRING = __ENCODING__ == "UTF-8"
     6
     7def assert_upto(exp, receiver, *args)
     8  act = []
     9  receiver.upto(*args) { |v| act << v }
     10  assert_equal exp, act
    5111end
    5212
    5313assert('String#dump') do
    54   ("\1" * 100).dump     # should not raise an exception - regress #1210
    55   "\0".inspect == "\"\\000\"" and
    56   "foo".dump == "\"foo\""
     14  assert_equal("\"\\x00\"", "\0".dump)
     15  assert_equal("\"foo\"", "foo".dump)
     16  assert_equal('"\xe3\x82\x8b"', "る".dump)
     17  assert_nothing_raised { ("\1" * 100).dump }   # regress #1210
    5718end
    5819
    5920assert('String#strip') do
    6021  s = "  abc  "
    61   "".strip == "" and " \t\r\n\f\v".strip == "" and
    62   "\0a\0".strip == "\0a" and
    63   "abc".strip     == "abc" and
    64   "  abc".strip   == "abc" and
    65   "abc  ".strip   == "abc" and
    66   "  abc  ".strip == "abc" and
    67   s == "  abc  "
     22  assert_equal("abc", s.strip)
     23  assert_equal("  abc  ", s)
     24  assert_equal("", "".strip)
     25  assert_equal("", " \t\r\n\f\v".strip)
     26  assert_equal("\0a", "\0a\0".strip)
     27  assert_equal("abc", "abc".strip)
     28  assert_equal("abc", "  abc".strip)
     29  assert_equal("abc", "abc  ".strip)
    6830end
    6931
    7032assert('String#lstrip') do
    7133  s = "  abc  "
    72   s.lstrip
    73   "".lstrip == "" and " \t\r\n\f\v".lstrip == "" and
    74   "\0a\0".lstrip == "\0a\0" and
    75   "abc".lstrip     == "abc"   and
    76   "  abc".lstrip   == "abc"   and
    77   "abc  ".lstrip   == "abc  " and
    78   "  abc  ".lstrip == "abc  " and
    79   s == "  abc  "
     34  assert_equal("abc  ", s.lstrip)
     35  assert_equal("  abc  ", s)
     36  assert_equal("", "".lstrip)
     37  assert_equal("", " \t\r\n\f\v".lstrip)
     38  assert_equal("\0a\0", "\0a\0".lstrip)
     39  assert_equal("abc", "abc".lstrip)
     40  assert_equal("abc", "  abc".lstrip)
     41  assert_equal("abc  ", "abc  ".lstrip)
    8042end
    8143
    8244assert('String#rstrip') do
    8345  s = "  abc  "
    84   s.rstrip
    85   "".rstrip == "" and " \t\r\n\f\v".rstrip == "" and
    86   "\0a\0".rstrip == "\0a" and
    87   "abc".rstrip     == "abc"   and
    88   "  abc".rstrip   == "  abc" and
    89   "abc  ".rstrip   == "abc"   and
    90   "  abc  ".rstrip == "  abc" and
    91   s == "  abc  "
     46  assert_equal("  abc", s.rstrip)
     47  assert_equal("  abc  ", s)
     48  assert_equal("", "".rstrip)
     49  assert_equal("", " \t\r\n\f\v".rstrip)
     50  assert_equal("\0a", "\0a\0".rstrip)
     51  assert_equal("abc", "abc".rstrip)
     52  assert_equal("  abc", "  abc".rstrip)
     53  assert_equal("abc", "abc  ".rstrip)
    9254end
    9355
     
    9557  s = "  abc  "
    9658  t = "abc"
    97   s.strip! == "abc" and s == "abc" and t.strip! == nil
     59  assert_equal("abc", s.strip!)
     60  assert_equal("abc", s)
     61  assert_nil(t.strip!)
     62  assert_equal("abc", t)
    9863end
    9964
     
    10166  s = "  abc  "
    10267  t = "abc  "
    103   s.lstrip! == "abc  " and s == "abc  " and t.lstrip! == nil
     68  assert_equal("abc  ", s.lstrip!)
     69  assert_equal("abc  ", s)
     70  assert_nil(t.lstrip!)
     71  assert_equal("abc  ", t)
    10472end
    10573
     
    10775  s = "  abc  "
    10876  t = "  abc"
    109   s.rstrip! == "  abc" and s == "  abc" and t.rstrip! == nil
     77  assert_equal("  abc", s.rstrip!)
     78  assert_equal("  abc", s)
     79  assert_nil(t.rstrip!)
     80  assert_equal("  abc", t)
    11081end
    11182
     
    12596  assert_equal "Hello World!", "Hello " << "World" << 33
    12697  assert_equal "Hello World!", "Hello ".concat("World").concat(33)
    127 
    128   o = Object.new
    129   def o.to_str
    130     "to_str"
    131   end
    132   assert_equal "hi to_str", "hi " << o
    133 
    13498  assert_raise(TypeError) { "".concat(Object.new) }
     99
     100  if UTF8STRING
     101    assert_equal "H«", "H" << 0xab
     102    assert_equal "Hは", "H" << 12399
     103  else
     104    assert_equal "H\xab", "H" << 0xab
     105    assert_raise(RangeError) { "H" << 12399 }
     106  end
    135107end
    136108
     
    140112  assert_equal(-1, "abcdef".casecmp("abcdefg"))
    141113  assert_equal 0, "abcdef".casecmp("ABCDEF")
    142   o = Object.new
    143   def o.to_str
    144     "ABCDEF"
    145   end
    146   assert_equal 0, "abcdef".casecmp(o)
     114end
     115
     116assert('String#count') do
     117  s = "abccdeff123"
     118  assert_equal 0, s.count("")
     119  assert_equal 1, s.count("a")
     120  assert_equal 2, s.count("ab")
     121  assert_equal 9, s.count("^c")
     122  assert_equal 8, s.count("a-z")
     123  assert_equal 4, s.count("a0-9")
     124end
     125
     126assert('String#tr') do
     127  assert_equal "ABC", "abc".tr('a-z', 'A-Z')
     128  assert_equal "hippo", "hello".tr('el', 'ip')
     129  assert_equal "Ruby", "Lisp".tr("Lisp", "Ruby")
     130  assert_equal "*e**o", "hello".tr('^aeiou', '*')
     131  assert_equal "heo", "hello".tr('l', '')
     132end
     133
     134assert('String#tr!') do
     135  s = "abcdefghijklmnopqR"
     136  assert_equal "ab12222hijklmnopqR", s.tr!("cdefg", "12")
     137  assert_equal "ab12222hijklmnopqR", s
     138end
     139
     140assert('String#tr_s') do
     141  assert_equal "hero", "hello".tr_s('l', 'r')
     142  assert_equal "h*o", "hello".tr_s('el', '*')
     143  assert_equal "hhxo", "hello".tr_s('el', 'hx')
     144end
     145
     146assert('String#tr_s!') do
     147  s = "hello"
     148  assert_equal "hero", s.tr_s!('l', 'r')
     149  assert_equal "hero", s
     150  assert_nil s.tr_s!('l', 'r')
     151end
     152
     153assert('String#squeeze') do
     154  assert_equal "yelow mon", "yellow moon".squeeze
     155  assert_equal " now is the", "  now   is  the".squeeze(" ")
     156  assert_equal "puters shot balls", "putters shoot balls".squeeze("m-z")
     157end
     158
     159assert('String#squeeze!') do
     160  s = "  now   is  the"
     161  assert_equal " now is the", s.squeeze!(" ")
     162  assert_equal " now is the", s
     163end
     164
     165assert('String#delete') do
     166  assert_equal "he", "hello".delete("lo")
     167  assert_equal "hll", "hello".delete("aeiou")
     168  assert_equal "ll", "hello".delete("^l")
     169  assert_equal "ho", "hello".delete("ej-m")
     170end
     171
     172assert('String#delete!') do
     173  s = "hello"
     174  assert_equal "he", s.delete!("lo")
     175  assert_equal "he", s
     176  assert_nil s.delete!("lz")
    147177end
    148178
     
    202232  assert_equal 8, "010".oct
    203233  assert_equal (-8), "-10".oct
    204 end
    205 
    206 assert('String#chr') do
    207   assert_equal "a", "abcde".chr
    208   # test Fixnum#chr as well
    209   assert_equal "a", 97.chr
    210234end
    211235
     
    496520
    497521assert('String#upto') do
    498   assert_equal %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8".upto("b6").to_a
    499   assert_equal ["9", "10", "11"], "9".upto("11").to_a
    500   assert_equal [], "25".upto("5").to_a
    501   assert_equal ["07", "08", "09", "10", "11"], "07".upto("11").to_a
    502 
    503 if UTF8STRING
    504   assert_equal ["あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お"], "あ".upto("お").to_a
    505 end
    506 
    507   assert_equal ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9".upto("A").to_a
     522  assert_upto %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8", "b6"
     523  assert_upto ["9", "10", "11"], "9", "11"
     524  assert_upto [], "25", "5"
     525  assert_upto ["07", "08", "09", "10", "11"], "07", "11"
     526  assert_upto ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9", "A"
     527
     528  if UTF8STRING
     529    assert_upto %w(あ ぃ い ぅ う ぇ え ぉ お), "あ", "お"
     530  end
    508531
    509532  a     = "aa"
     
    587610
    588611assert('String#chr') do
     612  assert_equal "a", "abcde".chr
    589613  assert_equal "h", "hello!".chr
    590 end
     614  assert_equal "", "".chr
     615end
     616
    591617assert('String#chr(UTF-8)') do
    592618  assert_equal "こ", "こんにちは世界!".chr
     
    614640
    615641assert('String#each_char') do
    616   s = ""
     642  chars = []
    617643  "hello!".each_char do |x|
    618     s += x
    619   end
    620   assert_equal "hello!", s
     644    chars << x
     645  end
     646  assert_equal ["h", "e", "l", "l", "o", "!"], chars
    621647end
    622648
    623649assert('String#each_char(UTF-8)') do
    624   s = ""
     650  chars = []
    625651  "こんにちは世界!".each_char do |x|
    626     s += x
    627   end
    628   assert_equal "こんにちは世界!", s
     652    chars << x
     653  end
     654  assert_equal ["こ", "ん", "に", "ち", "は", "世", "界", "!"], chars
    629655end if UTF8STRING
    630656
     
    666692  assert_equal expect, cp
    667693end if UTF8STRING
     694
     695assert('String#delete_prefix') do
     696  assert_equal "llo", "hello".delete_prefix("he")
     697  assert_equal "hello", "hello".delete_prefix("llo")
     698  assert_equal "llo", "hello".delete_prefix!("he")
     699  assert_nil "hello".delete_prefix!("llo")
     700end
     701
     702assert('String#delete_suffix') do
     703  assert_equal "he", "hello".delete_suffix("llo")
     704  assert_equal "hello", "hello".delete_suffix("he")
     705  assert_equal "he", "hello".delete_suffix!("llo")
     706  assert_nil "hello".delete_suffix!("he")
     707end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-struct/mrblib/struct.rb

    r331 r439  
    4747    end
    4848
    49     def _inspect
     49    def _inspect(recur_list)
     50      return "#<struct #{self.class}:...>" if recur_list[self.object_id]
     51      recur_list[self.object_id] = true
    5052      name = self.class.to_s
    5153      if name[0] == "#"
     
    5658      buf = []
    5759      self.each_pair do |k,v|
    58         buf.push [k.to_s + "=" + v._inspect]
     60        buf.push k.to_s + "=" + v._inspect(recur_list)
    5961      end
    6062      str + buf.join(", ") + ">"
     
    7173    #
    7274    def inspect
    73       begin
    74         self._inspect
    75       rescue SystemStackError
    76         "#<struct #{self.class.to_s}:...>"
    77       end
     75      self._inspect({})
    7876    end
    7977
     
    8280    #
    8381    alias to_s inspect
    84   end
    8582
    86   ##
    87   # call-seq:
    88   #   hsh.dig(key,...)                 -> object
    89   #
    90   # Extracts the nested value specified by the sequence of <i>key</i>
    91   # objects by calling +dig+ at each step, returning +nil+ if any
    92   # intermediate step is +nil+.
    93   #
    94   def dig(idx,*args)
    95     n = self[idx]
    96     if args.size > 0
    97       n&.dig(*args)
    98     else
    99       n
     83    ##
     84    # call-seq:
     85    #   hsh.dig(key,...)                 -> object
     86    #
     87    # Extracts the nested value specified by the sequence of <i>key</i>
     88    # objects by calling +dig+ at each step, returning +nil+ if any
     89    # intermediate step is +nil+.
     90    #
     91    def dig(idx,*args)
     92      n = self[idx]
     93      if args.size > 0
     94        n&.dig(*args)
     95      else
     96        n
     97      end
    10098    end
    10199  end
    102100end
    103 
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-struct/src/struct.c

    r331 r439  
    1313#include <mruby/hash.h>
    1414#include <mruby/range.h>
    15 
    16 #define RSTRUCT_LEN(st) mrb_ary_ptr(st)->len
    17 #define RSTRUCT_PTR(st) mrb_ary_ptr(st)->ptr
     15#include <mruby/proc.h>
     16
     17#define RSTRUCT_LEN(st) RARRAY_LEN(st)
     18#define RSTRUCT_PTR(st) RARRAY_PTR(st)
    1819
    1920static struct RClass *
     
    2425
    2526static inline mrb_value
    26 struct_ivar_get(mrb_state *mrb, mrb_value c, mrb_sym id)
    27 {
    28   struct RClass* kclass;
     27struct_ivar_get(mrb_state *mrb, mrb_value cls, mrb_sym id)
     28{
     29  struct RClass* c = mrb_class_ptr(cls);
    2930  struct RClass* sclass = struct_class(mrb);
    3031  mrb_value ans;
    3132
    3233  for (;;) {
    33     ans = mrb_iv_get(mrb, c, id);
     34    ans = mrb_iv_get(mrb, mrb_obj_value(c), id);
    3435    if (!mrb_nil_p(ans)) return ans;
    35     kclass = RCLASS_SUPER(c);
    36     if (kclass == 0 || kclass == sclass)
     36    c = c->super;
     37    if (c == sclass || c == 0)
    3738      return mrb_nil_value();
    38     c = mrb_obj_value(kclass);
    3939  }
    4040}
     
    6767    else {
    6868      mrb_raisef(mrb, E_TYPE_ERROR,
    69                  "struct size differs (%S required %S given)",
    70                  mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s)));
     69                 "struct size differs (%i required %i given)",
     70                 RARRAY_LEN(members), RSTRUCT_LEN(s));
    7171    }
    7272  }
     
    8888mrb_struct_modify(mrb_state *mrb, mrb_value strct)
    8989{
    90   if (MRB_FROZEN_P(mrb_basic_ptr(strct))) {
    91     mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct");
    92   }
    93 
     90  mrb_check_frozen(mrb, mrb_basic_ptr(strct));
    9491  mrb_write_barrier(mrb, mrb_basic_ptr(strct));
    9592}
     
    114111}
    115112
    116 static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id);
    117 
    118113static mrb_value
    119114mrb_struct_ref(mrb_state *mrb, mrb_value obj)
    120115{
    121   return struct_aref_sym(mrb, obj, mrb->c->ci->mid);
     116  mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0));
     117  mrb_value *ptr = RSTRUCT_PTR(obj);
     118
     119  if (!ptr) return mrb_nil_value();
     120  return ptr[i];
    122121}
    123122
     
    125124mrb_id_attrset(mrb_state *mrb, mrb_sym id)
    126125{
     126#define ONSTACK_ALLOC_MAX 32
     127#define ONSTACK_STRLEN_MAX (ONSTACK_ALLOC_MAX - 1) /* '=' character */
     128
    127129  const char *name;
    128130  char *buf;
    129131  mrb_int len;
    130132  mrb_sym mid;
    131 
    132   name = mrb_sym2name_len(mrb, id, &len);
    133   buf = (char *)mrb_malloc(mrb, (size_t)len+2);
     133  char onstack[ONSTACK_ALLOC_MAX];
     134
     135  name = mrb_sym_name_len(mrb, id, &len);
     136  if (len > ONSTACK_STRLEN_MAX) {
     137    buf = (char *)mrb_malloc(mrb, (size_t)len+1);
     138  }
     139  else {
     140    buf = onstack;
     141  }
    134142  memcpy(buf, name, (size_t)len);
    135143  buf[len] = '=';
    136   buf[len+1] = '\0';
    137144
    138145  mid = mrb_intern(mrb, buf, len+1);
    139   mrb_free(mrb, buf);
     146  if (buf != onstack) {
     147    mrb_free(mrb, buf);
     148  }
    140149  return mid;
    141150}
    142151
    143 static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val);
    144 
    145152static mrb_value
    146153mrb_struct_set_m(mrb_state *mrb, mrb_value obj)
    147154{
     155  mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0));
     156  mrb_value *ptr;
    148157  mrb_value val;
    149158
    150   const char *name;
    151   mrb_int slen;
    152   mrb_sym mid;
    153 
    154159  mrb_get_args(mrb, "o", &val);
    155 
    156   /* get base id */
    157   name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen);
    158   mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */
    159 
    160   return mrb_struct_aset_sym(mrb, obj, mid, val);
    161 }
    162 
    163 static mrb_bool
    164 is_local_id(mrb_state *mrb, const char *name)
    165 {
    166   if (!name) return FALSE;
    167   return !ISUPPER(name[0]);
    168 }
    169 
    170 static mrb_bool
    171 is_const_id(mrb_state *mrb, const char *name)
    172 {
    173   if (!name) return FALSE;
    174   return ISUPPER(name[0]);
     160  mrb_struct_modify(mrb, obj);
     161  ptr = RSTRUCT_PTR(obj);
     162  if (ptr == NULL || i >= RSTRUCT_LEN(obj)) {
     163    mrb_ary_set(mrb, obj, i, val);
     164  }
     165  else {
     166    ptr[i] = val;
     167  }
     168  return val;
    175169}
    176170
     
    185179  for (i=0; i<len; i++) {
    186180    mrb_sym id = mrb_symbol(ptr_members[i]);
    187     const char *name = mrb_sym2name_len(mrb, id, NULL);
    188 
    189     if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
    190       mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE());
    191       mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1));
    192       mrb_gc_arena_restore(mrb, ai);
    193     }
    194   }
    195 }
    196 
    197 static mrb_value
    198 make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass)
     181    mrb_method_t m;
     182    mrb_value at = mrb_fixnum_value(i);
     183    struct RProc *aref = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_ref, 1, &at);
     184    struct RProc *aset = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_set_m, 1, &at);
     185    MRB_METHOD_FROM_PROC(m, aref);
     186    mrb_define_method_raw(mrb, c, id, m);
     187    MRB_METHOD_FROM_PROC(m, aset);
     188    mrb_define_method_raw(mrb, c, mrb_id_attrset(mrb, id), m);
     189    mrb_gc_arena_restore(mrb, ai);
     190  }
     191}
     192
     193static mrb_value
     194make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *klass)
    199195{
    200196  mrb_value nstr;
     
    207203  else {
    208204    /* old style: should we warn? */
    209     name = mrb_str_to_str(mrb, name);
     205    mrb_to_str(mrb, name);
    210206    id = mrb_obj_to_sym(mrb, name);
    211     if (!is_const_id(mrb, mrb_sym2name_len(mrb, id, NULL))) {
    212       mrb_name_error(mrb, id, "identifier %S needs to be constant", name);
     207    if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) {
     208      mrb_name_error(mrb, id, "identifier %v needs to be constant", name);
    213209    }
    214210    if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) {
    215       mrb_warn(mrb, "redefining constant Struct::%S", name);
     211      mrb_warn(mrb, "redefining constant Struct::%v", name);
    216212      mrb_const_remove(mrb, mrb_obj_value(klass), id);
    217213    }
     
    277273
    278274  name = mrb_nil_value();
    279   rest = mrb_nil_value();
    280275  mrb_get_args(mrb, "*&", &argv, &argc, &b);
    281276  if (argc == 0) { /* special case to avoid crash */
    282     rest = mrb_ary_new(mrb);
     277    mrb_argnum_error(mrb, argc, 1, -1);
    283278  }
    284279  else {
    285     if (argc > 0) name = argv[0];
    286     pargv = &argv[1];
    287     argcnt = argc-1;
    288     if (!mrb_nil_p(name) && mrb_symbol_p(name)) {
    289       /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */
    290       name = mrb_nil_value();
    291       pargv = &argv[0];
    292       argcnt++;
     280    pargv = argv;
     281    argcnt = argc;
     282    if (argc > 0) {
     283      name = argv[0];
     284      if (mrb_symbol_p(name)) {
     285        /* 1stArgument:symbol -> name=nil rest=argv[0..n] */
     286        name = mrb_nil_value();
     287      }
     288      else {
     289        pargv++;
     290        argcnt--;
     291      }
    293292    }
    294293    rest = mrb_ary_new_from_values(mrb, argcnt, pargv);
    295     for (i=0; i<RARRAY_LEN(rest); i++) {
     294    for (i=0; i<argcnt; i++) {
    296295      id = mrb_obj_to_sym(mrb, RARRAY_PTR(rest)[i]);
    297296      mrb_ary_set(mrb, rest, i, mrb_symbol_value(id));
    298297    }
    299   }
    300   st = make_struct(mrb, name, rest, mrb_class_ptr(klass));
    301   if (!mrb_nil_p(b)) {
    302     mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st));
    303   }
    304 
    305   return st;
     298    st = make_struct(mrb, name, rest, mrb_class_ptr(klass));
     299    if (!mrb_nil_p(b)) {
     300      mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st));
     301    }
     302
     303    return st;
     304  }
     305  /* not reached */
     306  return mrb_nil_value();
    306307}
    307308
     
    347348  mrb_int argc;
    348349
    349   mrb_get_args(mrb, "*", &argv, &argc);
     350  mrb_get_args(mrb, "*!", &argv, &argc);
    350351  return mrb_struct_initialize_withArg(mrb, argc, argv, self);
    351352}
     
    388389    }
    389390  }
    390   mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id));
     391  mrb_name_error(mrb, id, "no member '%n' in struct", id);
    391392  return mrb_nil_value();       /* not reached */
    392393}
     
    395396struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i)
    396397{
    397   if (i < 0) i = RSTRUCT_LEN(s) + i;
    398   if (i < 0)
    399       mrb_raisef(mrb, E_INDEX_ERROR,
    400                  "offset %S too small for struct(size:%S)",
    401                  mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
    402   if (RSTRUCT_LEN(s) <= i)
     398  mrb_int idx = i < 0 ? RSTRUCT_LEN(s) + i : i;
     399
     400  if (idx < 0)
    403401    mrb_raisef(mrb, E_INDEX_ERROR,
    404                "offset %S too large for struct(size:%S)",
    405                mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
    406   return RSTRUCT_PTR(s)[i];
     402               "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s));
     403  if (RSTRUCT_LEN(s) <= idx)
     404    mrb_raisef(mrb, E_INDEX_ERROR,
     405               "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s));
     406  return RSTRUCT_PTR(s)[idx];
    407407}
    408408
     
    436436
    437437    if (mrb_nil_p(sym)) {
    438       mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
     438      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx);
    439439    }
    440440    idx = sym;
     
    464464    }
    465465  }
    466   mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id));
     466  mrb_name_error(mrb, id, "no member '%n' in struct", id);
    467467  return val;                   /* not reach */
    468468}
     
    503503
    504504    if (mrb_nil_p(sym)) {
    505       mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
     505      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx);
    506506    }
    507507    idx = sym;
     
    515515  if (i < 0) {
    516516    mrb_raisef(mrb, E_INDEX_ERROR,
    517                "offset %S too small for struct(size:%S)",
    518                mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
     517               "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s));
    519518  }
    520519  if (RSTRUCT_LEN(s) <= i) {
    521520    mrb_raisef(mrb, E_INDEX_ERROR,
    522                "offset %S too large for struct(size:%S)",
    523                mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
     521               "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s));
    524522  }
    525523  mrb_struct_modify(mrb, s);
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-struct/test/struct.rb

    r331 r439  
    1010  assert_equal Struct, c.superclass
    1111  assert_equal [:m1, :m2], c.members
    12 end
    13 
    14 # Check crash bug with Struc.new and no params.
    15 assert('Struct.new', '15.2.18.3.1') do
    16   c = Struct.new()
    17   assert_equal Struct, c.superclass
    18   assert_equal [], c.members
    1912end
    2013
     
    124117
    125118assert('struct inspect') do
    126   c = Struct.new(:m1, :m2, :m3, :m4, :m5)
    127   cc = c.new(1,2,3,4,5)
    128   assert_equal "#<struct m1=1, m2=2, m3=3, m4=4, m5=5>", cc.inspect
     119  c = Struct.new(:m1, :m2, :m3, :m4, :m5, :recur)
     120  cc = c.new(1,2,3,4,5,nil)
     121  cc.recur = cc
     122  assert_equal "#<struct m1=1, m2=2, m3=3, m4=4, m5=5, recur=#<struct #{cc.class}:...>>", cc.inspect
    129123end
    130124
     
    160154end
    161155
    162 assert("Struct.new removes existing constant") do
    163   skip "redefining Struct with same name cause warnings"
    164   begin
    165     assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)
    166   ensure
    167     Struct.remove_const :Test
    168   end
    169 end
     156# TODO: suppress redefining Struct warning during test
     157# assert("Struct.new removes existing constant") do
     158#   begin
     159#     assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)
     160#   ensure
     161#     Struct.remove_const :Test
     162#   end
     163# end
    170164
    171165assert("Struct#initialize_copy requires struct to be the same type") do
     
    189183end
    190184
     185assert("Struct.new does not allow invalid class name") do
     186  assert_raise(NameError) { Struct.new("Test-", :a) }
     187end
     188
    191189assert("Struct.new generates subclass of Struct") do
    192190  begin
    193191    original_struct = Struct
    194192    Struct = String
    195     assert_equal original_struct, original_struct.new.superclass
     193    assert_equal original_struct, original_struct.new(:foo).superclass
    196194  ensure
    197195    Struct = original_struct
     
    207205
    208206  o.freeze
    209   assert_raise(RuntimeError) { o.m = :modify }
    210   assert_raise(RuntimeError) { o[:m] = :modify }
     207  assert_raise(FrozenError) { o.m = :modify }
     208  assert_raise(FrozenError) { o[:m] = :modify }
    211209  assert_equal :test, o.m
    212210end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-symbol-ext/mrblib/symbol.rb

    r321 r439  
    33
    44  alias intern to_sym
    5 
    6   def to_proc
    7     ->(obj,*args,&block) do
    8       obj.__send__(self, *args, &block)
    9     end
    10   end
    115
    126  ##
     
    4943    return nil unless other.kind_of?(Symbol)
    5044    lhs =  self.to_s; lhs.upcase!
    51     rhs = other.to_s; rhs.upcase!
     45    rhs = other.to_s.upcase
    5246    lhs <=> rhs
     47  end
     48
     49  ##
     50  # call-seq:
     51  #   sym.casecmp?(other)  -> true, false, or nil
     52  #
     53  # Returns true if sym and other_sym are equal after case folding,
     54  # false if they are not equal, and nil if other_sym is not a string.
     55
     56  def casecmp?(sym)
     57    c = self.casecmp(sym)
     58    return nil if c.nil?
     59    return c == 0
    5360  end
    5461
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-symbol-ext/src/symbol.c

    r331 r439  
    22#include <mruby/khash.h>
    33#include <mruby/array.h>
    4 
    5 typedef struct symbol_name {
    6   size_t len;
    7   const char *name;
    8 } symbol_name;
     4#include <mruby/string.h>
    95
    106/*
     
    2319 *                                     :wait2, :$>]
    2420 */
     21#ifdef MRB_ENABLE_ALL_SYMBOLS
    2522static mrb_value
    2623mrb_sym_all_symbols(mrb_state *mrb, mrb_value self)
     
    3027
    3128  for (i=1, lim=mrb->symidx+1; i<lim; i++) {
    32     mrb_ary_push(mrb, ary, mrb_symbol_value(i));
     29    mrb_sym sym = i<<1;
     30    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
    3331  }
    3432
    3533  return ary;
    3634}
     35#endif
    3736
    3837/*
     
    4645{
    4746  mrb_int len;
    48   mrb_sym2name_len(mrb, mrb_symbol(self), &len);
     47#ifdef MRB_UTF8_STRING
     48  mrb_int byte_len;
     49  const char *name = mrb_sym_name_len(mrb, mrb_symbol(self), &byte_len);
     50  len = mrb_utf8_strlen(name, byte_len);
     51#else
     52  mrb_sym_name_len(mrb, mrb_symbol(self), &len);
     53#endif
    4954  return mrb_fixnum_value(len);
    5055}
     
    5459{
    5560  struct RClass *s = mrb->symbol_class;
     61#ifdef MRB_ENABLE_ALL_SYMBOLS
    5662  mrb_define_class_method(mrb, s, "all_symbols", mrb_sym_all_symbols, MRB_ARGS_NONE());
     63#endif
    5764  mrb_define_method(mrb, s, "length", mrb_sym_length, MRB_ARGS_NONE());
    5865  mrb_define_method(mrb, s, "size", mrb_sym_length, MRB_ARGS_NONE());
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-symbol-ext/test/symbol.rb

    r321 r439  
     1# coding: utf-8
    12##
    23# Symbol(Ext) Test
    34
    4 assert('Symbol#to_proc') do
    5   assert_equal 5, :abs.to_proc[-5]
     5if Symbol.respond_to?(:all_symbols)
     6  assert('Symbol.all_symbols') do
     7    foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort
     8    symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort
     9    assert_equal foo, symbols
     10  end
    611end
    712
    8 assert('Symbol.all_symbols') do
    9   foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort
    10   symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort
    11   assert_equal foo, symbols
    12 end
    13 
    14 assert("Symbol#length") do
    15   assert_equal 5, :hello.size
    16   assert_equal 5, :mruby.length
     13%w[size length].each do |n|
     14  assert("Symbol##{n}") do
     15    assert_equal 5, :hello.__send__(n)
     16    assert_equal 4, :"aA\0b".__send__(n)
     17    if __ENCODING__ == "UTF-8"
     18      assert_equal 8, :"こんにちは世界!".__send__(n)
     19      assert_equal 4, :"aあ\0b".__send__(n)
     20    else
     21      assert_equal 22, :"こんにちは世界!".__send__(n)
     22      assert_equal 6, :"aあ\0b".__send__(n)
     23    end
     24  end
    1725end
    1826
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-test/driver.c

    r331 r439  
    1919#include <mruby/array.h>
    2020
    21 void
    22 mrb_init_mrbtest(mrb_state *);
     21extern const uint8_t mrbtest_assert_irep[];
     22
     23void mrbgemtest_init(mrb_state* mrb);
     24void mrb_init_test_vformat(mrb_state* mrb);
    2325
    2426/* Print a short remark for the user */
     
    3032
    3133static int
    32 check_error(mrb_state *mrb)
    33 {
    34   /* Error check */
    35   /* $ko_test and $kill_test should be 0 */
    36   mrb_value ko_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$ko_test"));
    37   mrb_value kill_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$kill_test"));
    38 
    39   return mrb_fixnum_p(ko_test) && mrb_fixnum(ko_test) == 0 && mrb_fixnum_p(kill_test) && mrb_fixnum(kill_test) == 0;
    40 }
    41 
    42 static int
    4334eval_test(mrb_state *mrb)
    4435{
    4536  /* evaluate the test */
    46   mrb_funcall(mrb, mrb_top_self(mrb), "report", 0);
     37  mrb_value result = mrb_funcall(mrb, mrb_top_self(mrb), "report", 0);
    4738  /* did an exception occur? */
    4839  if (mrb->exc) {
     
    5142    return EXIT_FAILURE;
    5243  }
    53   else if (!check_error(mrb)) {
    54     return EXIT_FAILURE;
    55   }
    56   return EXIT_SUCCESS;
    57 }
    58 
    59 static void
    60 t_printstr(mrb_state *mrb, mrb_value obj)
    61 {
    62   char *s;
    63   int len;
    64 
    65   if (mrb_string_p(obj)) {
    66     s = RSTRING_PTR(obj);
    67     len = RSTRING_LEN(obj);
    68     fwrite(s, len, 1, stdout);
    69   }
    70 }
    71 
    72 mrb_value
    73 mrb_t_printstr(mrb_state *mrb, mrb_value self)
    74 {
    75   mrb_value argv;
    76 
    77   mrb_get_args(mrb, "o", &argv);
    78   t_printstr(mrb, argv);
    79 
    80   return argv;
     44  else {
     45    return mrb_bool(result) ? EXIT_SUCCESS : EXIT_FAILURE;
     46  }
     47}
     48
     49/* Implementation of print due to the reason that there might be no print */
     50static mrb_value
     51t_print(mrb_state *mrb, mrb_value self)
     52{
     53  mrb_value *argv;
     54  mrb_int argc;
     55  mrb_int i;
     56
     57  mrb_get_args(mrb, "*!", &argv, &argc);
     58  for (i = 0; i < argc; ++i) {
     59    mrb_value s = mrb_obj_as_string(mrb, argv[i]);
     60    fwrite(RSTRING_PTR(s), RSTRING_LEN(s), 1, stdout);
     61  }
     62  fflush(stdout);
     63
     64  return mrb_nil_value();
     65}
     66
     67#define UNESCAPE(p, endp) ((p) != (endp) && *(p) == '\\' ? (p)+1 : (p))
     68#define CHAR_CMP(c1, c2) ((unsigned char)(c1) - (unsigned char)(c2))
     69
     70static const char *
     71str_match_bracket(const char *p, const char *pat_end,
     72                  const char *s, const char *str_end)
     73{
     74  mrb_bool ok = FALSE, negated = FALSE;
     75
     76  if (p == pat_end) return NULL;
     77  if (*p == '!' || *p == '^') {
     78    negated = TRUE;
     79    ++p;
     80  }
     81
     82  while (*p != ']') {
     83    const char *t1 = p;
     84    if ((t1 = UNESCAPE(t1, pat_end)) == pat_end) return NULL;
     85    if ((p = t1 + 1) == pat_end) return NULL;
     86    if (p[0] == '-' && p[1] != ']') {
     87      const char *t2 = p + 1;
     88      if ((t2 = UNESCAPE(t2, pat_end)) == pat_end) return NULL;
     89      p = t2 + 1;
     90      if (!ok && CHAR_CMP(*t1, *s) <= 0 && CHAR_CMP(*s, *t2) <= 0) ok = TRUE;
     91    }
     92    else {
     93      if (!ok && CHAR_CMP(*t1, *s) == 0) ok = TRUE;
     94    }
     95  }
     96
     97  return ok == negated ? NULL : p + 1;
     98}
     99
     100static mrb_bool
     101str_match_no_brace_p(const char *pat, mrb_int pat_len,
     102                     const char *str, mrb_int str_len)
     103{
     104  const char *p = pat, *s = str;
     105  const char *pat_end = pat + pat_len, *str_end = str + str_len;
     106  const char *p_tmp = NULL, *s_tmp = NULL;
     107
     108  for (;;) {
     109    if (p == pat_end) return s == str_end;
     110    switch (*p) {
     111      case '*':
     112        do { ++p; } while (p != pat_end && *p == '*');
     113        if (UNESCAPE(p, pat_end) == pat_end) return TRUE;
     114        if (s == str_end) return FALSE;
     115        p_tmp = p;
     116        s_tmp = s;
     117        continue;
     118      case '?':
     119        if (s == str_end) return FALSE;
     120        ++p;
     121        ++s;
     122        continue;
     123      case '[': {
     124        const char *t;
     125        if (s == str_end) return FALSE;
     126        if ((t = str_match_bracket(p+1, pat_end, s, str_end))) {
     127          p = t;
     128          ++s;
     129          continue;
     130        }
     131        goto L_failed;
     132      }
     133    }
     134
     135    /* ordinary */
     136    p = UNESCAPE(p, pat_end);
     137    if (s == str_end) return p == pat_end;
     138    if (p == pat_end) goto L_failed;
     139    if (*p++ != *s++) goto L_failed;
     140    continue;
     141
     142    L_failed:
     143    if (p_tmp && s_tmp) {
     144      /* try next '*' position */
     145      p = p_tmp;
     146      s = ++s_tmp;
     147      continue;
     148    }
     149
     150    return FALSE;
     151  }
     152}
     153
     154#define COPY_AND_INC(dst, src, len) \
     155  do { memcpy(dst, src, len); dst += len; } while (0)
     156
     157static mrb_bool
     158str_match_p(mrb_state *mrb,
     159            const char *pat, mrb_int pat_len,
     160            const char *str, mrb_int str_len)
     161{
     162  const char *p = pat, *pat_end = pat + pat_len;
     163  const char *lbrace = NULL, *rbrace = NULL;
     164  int nest = 0;
     165  mrb_bool ret = FALSE;
     166
     167  for (; p != pat_end; ++p) {
     168    if (*p == '{' && nest++ == 0) lbrace = p;
     169    else if (*p == '}' && lbrace && --nest == 0) { rbrace = p; break; }
     170    else if (*p == '\\' && ++p == pat_end) break;
     171  }
     172
     173  if (lbrace && rbrace) {
     174    /* expand brace */
     175    char *ex_pat = (char *)mrb_malloc(mrb, pat_len-2);  /* expanded pattern */
     176    char *ex_p = ex_pat;
     177
     178    COPY_AND_INC(ex_p, pat, lbrace-pat);
     179    p = lbrace;
     180    while (p < rbrace) {
     181      char *orig_ex_p = ex_p;
     182      const char *t = ++p;
     183      for (nest = 0; p < rbrace && !(*p == ',' && nest == 0); ++p) {
     184        if (*p == '{') ++nest;
     185        else if (*p == '}') --nest;
     186        else if (*p == '\\' && ++p == rbrace) break;
     187      }
     188      COPY_AND_INC(ex_p, t, p-t);
     189      COPY_AND_INC(ex_p, rbrace+1, pat_end-rbrace-1);
     190      if ((ret = str_match_p(mrb, ex_pat, ex_p-ex_pat, str, str_len))) break;
     191      ex_p = orig_ex_p;
     192    }
     193    mrb_free(mrb, ex_pat);
     194  }
     195  else if (!lbrace && !rbrace) {
     196    ret = str_match_no_brace_p(pat, pat_len, str, str_len);
     197  }
     198
     199  return ret;
     200}
     201
     202static mrb_value
     203m_str_match_p(mrb_state *mrb, mrb_value self)
     204{
     205  const char *pat, *str;
     206  mrb_int pat_len, str_len;
     207
     208  mrb_get_args(mrb, "ss", &pat, &pat_len, &str, &str_len);
     209  return mrb_bool_value(str_match_p(mrb, pat, pat_len, str, str_len));
    81210}
    82211
     
    87216
    88217  krn = mrb->kernel_module;
    89   mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1));
     218  mrb_define_method(mrb, krn, "t_print", t_print, MRB_ARGS_ANY());
     219  mrb_define_method(mrb, krn, "_str_match?", m_str_match_p, MRB_ARGS_REQ(2));
    90220
    91221  mrbtest = mrb_define_module(mrb, "Mrbtest");
     
    95225  mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT));
    96226
     227#ifndef MRB_WITHOUT_FLOAT
    97228#ifdef MRB_USE_FLOAT
    98229  mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-6));
     
    100231  mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-12));
    101232#endif
     233#endif
     234
     235  mrb_init_test_vformat(mrb);
    102236
    103237  if (verbose) {
     
    128262  TEST_COUNT_PASS(ko_test);
    129263  TEST_COUNT_PASS(kill_test);
     264  TEST_COUNT_PASS(warning_test);
     265  TEST_COUNT_PASS(skip_test);
    130266
    131267#undef TEST_COUNT_PASS
     
    165301
    166302  mrb_init_test_driver(mrb, verbose);
    167   mrb_init_mrbtest(mrb);
     303  mrb_load_irep(mrb, mrbtest_assert_irep);
     304  mrbgemtest_init(mrb);
    168305  ret = eval_test(mrb);
    169306  mrb_close(mrb);
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-test/mrbgem.rake

    r331 r439  
    1313  exec = exefile("#{build.build_dir}/bin/mrbtest")
    1414
    15   libmruby = libfile("#{build.build_dir}/lib/libmruby")
    16   libmruby_core = libfile("#{build.build_dir}/lib/libmruby_core")
    17 
    1815  mrbtest_lib = libfile("#{build_dir}/mrbtest")
    1916  mrbtest_objs = []
    2017
    21   driver_obj = objfile("#{build_dir}/driver")
    22   driver = "#{spec.dir}/driver.c"
     18  driver_objs = Dir.glob("#{dir}/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f|
     19    objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X"))
     20  end
    2321
    2422  assert_c = "#{build_dir}/assert.c"
     
    2826
    2927  file assert_lib => assert_c
    30   file assert_c => assert_rb do |t|
     28  file assert_c => [assert_rb, build.mrbcfile] do |t|
    3129    open(t.name, 'w') do |f|
    3230      mrbc.run f, assert_rb, 'mrbtest_assert_irep'
     
    4240
    4341    file test_rbobj => g.test_rbireps
    44     file g.test_rbireps => [g.test_rbfiles].flatten do |t|
    45       FileUtils.mkdir_p File.dirname(t.name)
     42    file g.test_rbireps => [g.test_rbfiles, build.mrbcfile].flatten do |t|
     43      mkdir_p File.dirname(t.name)
    4644      open(t.name, 'w') do |f|
    4745        g.print_gem_test_header(f)
     
    9896            f.puts %Q[  if (mrb2->exc) {]
    9997            f.puts %Q[    mrb_print_error(mrb2);]
     98            f.puts %Q[    mrb_close(mrb2);]
    10099            f.puts %Q[    exit(EXIT_FAILURE);]
    101100            f.puts %Q[  }]
     
    136135
    137136  unless build.build_mrbtest_lib_only?
    138     file exec => [driver_obj, mlib, mrbtest_lib, libmruby_core, libmruby] do |t|
     137    file exec => [*driver_objs, mlib, mrbtest_lib, build.libmruby_static] do |t|
    139138      gem_flags = build.gems.map { |g| g.linker.flags }
    140139      gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries }
     
    142141      gem_libraries = build.gems.map { |g| g.linker.libraries }
    143142      gem_library_paths = build.gems.map { |g| g.linker.library_paths }
    144       build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries
     143      build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags,
     144                       gem_flags_before_libraries, gem_flags_after_libraries
    145145    end
    146146  end
    147 
    148   init = "#{spec.dir}/init_mrbtest.c"
    149147
    150148  # store the last gem selection and make the re-build
    151149  # of the test gem depending on a change to the gem
    152150  # selection
    153   active_gems = "#{build_dir}/active_gems.lst"
    154   FileUtils.mkdir_p File.dirname(active_gems)
    155   open(active_gems, 'w+') do |f|
    156     build.gems.each do |g|
    157       f.puts g.name
    158     end
     151  active_gems_path = "#{build_dir}/active_gems_path.lst"
     152  active_gem_list = File.read active_gems_path if File.exist? active_gems_path
     153  current_gem_list = build.gems.map(&:name).join("\n")
     154  task active_gems_path do |_t|
     155    mkdir_p File.dirname(active_gems_path)
     156    File.write active_gems_path, current_gem_list
    159157  end
    160   file clib => active_gems
     158  file clib => active_gems_path if active_gem_list != current_gem_list
    161159
    162160  file mlib => clib
    163   file clib => init do |t|
     161  file clib => [build.mrbcfile, __FILE__] do |_t|
    164162    _pp "GEN", "*.rb", "#{clib.relative_path}"
    165     FileUtils.mkdir_p File.dirname(clib)
     163    mkdir_p File.dirname(clib)
    166164    open(clib, 'w') do |f|
    167165      f.puts %Q[/*]
     
    174172      f.puts %Q[ */]
    175173      f.puts %Q[]
    176       f.puts IO.read(init)
     174      f.puts %Q[struct mrb_state;]
     175      f.puts %Q[typedef struct mrb_state mrb_state;]
    177176      build.gems.each do |g|
    178177        f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);]
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-time/src/time.c

    r331 r439  
    55*/
    66
     7#ifndef MRB_WITHOUT_FLOAT
    78#include <math.h>
    8 #include <time.h>
     9#endif
     10
    911#include <mruby.h>
    1012#include <mruby/class.h>
    1113#include <mruby/data.h>
    12 
    13 #ifndef DISABLE_STDIO
    14 #include <stdio.h>
    15 #else
     14#include <mruby/numeric.h>
     15#include <mruby/time.h>
     16
     17#ifdef MRB_DISABLE_STDIO
    1618#include <string.h>
    1719#endif
    1820
     21#include <stdlib.h>
     22
    1923#define NDIV(x,y) (-(-((x)+1)/(y))-1)
    20 
    21 #if _MSC_VER < 1800
     24#define TO_S_FMT "%Y-%m-%d %H:%M:%S "
     25
     26#if defined(_MSC_VER) && _MSC_VER < 1800
    2227double round(double x) {
    23   if (x >= 0.0) {
    24     return (double)((int)(x + 0.5));
    25   }
    26   else {
    27     return (double)((int)(x - 0.5));
    28   }
    29 }
    30 #endif
    31 
    32 #if !defined(__MINGW64__) && defined(_WIN32)
    33 # define llround(x) round(x)
     28  return floor(x + 0.5);
     29}
     30#endif
     31
     32#ifndef MRB_WITHOUT_FLOAT
     33# if !defined(__MINGW64__) && defined(_WIN32)
     34#  define llround(x) round(x)
     35# endif
    3436#endif
    3537
     
    5254
    5355#ifdef _WIN32
    54 #if _MSC_VER
     56#ifdef _MSC_VER
    5557/* Win32 platform do not provide gmtime_r/localtime_r; emulate them using gmtime_s/localtime_s */
    5658#define gmtime_r(tp, tm)    ((gmtime_s((tm), (tp)) == 0) ? (tm) : NULL)
     
    144146  unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+1900)];
    145147
    146   for (i = 70; i < tm->tm_year; ++i)
    147     r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60;
     148  static const int epoch_year = 70;
     149  if(tm->tm_year >= epoch_year) {
     150    for (i = epoch_year; i < tm->tm_year; ++i)
     151      r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60;
     152  } else {
     153    for (i = tm->tm_year; i < epoch_year; ++i)
     154      r -= is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60;
     155  }
    148156  for (i = 0; i < tm->tm_mon; ++i)
    149157    r += nday[i] * 24 * 60 * 60;
     
    161169*/
    162170
    163 enum mrb_timezone {
    164   MRB_TIMEZONE_NONE   = 0,
    165   MRB_TIMEZONE_UTC    = 1,
    166   MRB_TIMEZONE_LOCAL  = 2,
    167   MRB_TIMEZONE_LAST   = 3
    168 };
    169 
    170171typedef struct mrb_timezone_name {
    171172  const char name[8];
     
    179180};
    180181
    181 #ifndef DISABLE_STDIO
     182#ifndef MRB_DISABLE_STDIO
    182183static const char mon_names[12][4] = {
    183184  "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
     
    198199static const struct mrb_data_type mrb_time_type = { "Time", mrb_free };
    199200
     201#ifndef MRB_WITHOUT_FLOAT
     202void mrb_check_num_exact(mrb_state *mrb, mrb_float num);
     203typedef mrb_float mrb_sec;
     204#define mrb_sec_value(mrb, sec) mrb_float_value(mrb, sec)
     205#else
     206typedef mrb_int mrb_sec;
     207#define mrb_sec_value(mrb, sec) mrb_fixnum_value(sec)
     208#endif
     209
     210#define MRB_TIME_T_UINT (~(time_t)0 > 0)
     211#define MRB_TIME_MIN (                                                      \
     212  MRB_TIME_T_UINT ? 0 :                                                     \
     213                    (sizeof(time_t) <= 4 ? INT32_MIN : INT64_MIN)           \
     214)
     215#define MRB_TIME_MAX (                                                      \
     216  MRB_TIME_T_UINT ? (sizeof(time_t) <= 4 ? UINT32_MAX : UINT64_MAX) :       \
     217                    (sizeof(time_t) <= 4 ? INT32_MAX : INT64_MAX)           \
     218)
     219
     220static mrb_bool
     221fixable_time_t_p(time_t v)
     222{
     223  if (MRB_INT_MIN <= MRB_TIME_MIN && MRB_TIME_MAX <= MRB_INT_MAX) return TRUE;
     224  return FIXABLE(v);
     225}
     226
     227static time_t
     228mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec)
     229{
     230  time_t t;
     231
     232  switch (mrb_type(obj)) {
     233#ifndef MRB_WITHOUT_FLOAT
     234    case MRB_TT_FLOAT:
     235      {
     236        mrb_float f = mrb_float(obj);
     237
     238        mrb_check_num_exact(mrb, f);
     239        if (f >= ((mrb_float)MRB_TIME_MAX-1.0) || f < ((mrb_float)MRB_TIME_MIN+1.0)) {
     240          goto out_of_range;
     241        }
     242
     243        if (usec) {
     244          t = (time_t)f;
     245          *usec = (time_t)llround((f - t) * 1.0e+6);
     246        }
     247        else {
     248          t = (time_t)llround(f);
     249        }
     250      }
     251      break;
     252#endif /* MRB_WITHOUT_FLOAT */
     253    default:
     254    case MRB_TT_FIXNUM:
     255      {
     256        mrb_int i = mrb_int(mrb, obj);
     257
     258        if ((MRB_INT_MAX > MRB_TIME_MAX && i > 0 && i > (mrb_int)MRB_TIME_MAX) ||
     259            (MRB_TIME_MIN > MRB_INT_MIN && MRB_TIME_MIN > i)) {
     260          goto out_of_range;
     261        }
     262
     263        t = (time_t)i;
     264        if (usec) { *usec = 0; }
     265      }
     266      break;
     267  }
     268
     269  return t;
     270
     271out_of_range:
     272  mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", obj);
     273
     274  /* not reached */
     275  if (usec) { *usec = 0; }
     276  return 0;
     277}
     278
    200279/** Updates the datetime of a mrb_time based on it's timezone and
    201 seconds setting. Returns self on success, NULL of failure. */
     280    seconds setting. Returns self on success, NULL of failure.
     281    if `dealloc` is set `true`, it frees `self` on error. */
    202282static struct mrb_time*
    203 time_update_datetime(mrb_state *mrb, struct mrb_time *self)
     283time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc)
    204284{
    205285  struct tm *aid;
     286  time_t t = self->sec;
    206287
    207288  if (self->timezone == MRB_TIMEZONE_UTC) {
    208     aid = gmtime_r(&self->sec, &self->datetime);
     289    aid = gmtime_r(&t, &self->datetime);
    209290  }
    210291  else {
    211     aid = localtime_r(&self->sec, &self->datetime);
     292    aid = localtime_r(&t, &self->datetime);
    212293  }
    213294  if (!aid) {
    214     mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, (mrb_float)self->sec));
     295    mrb_sec sec = (mrb_sec)t;
     296
     297    if (dealloc) mrb_free(mrb, self);
     298    mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", mrb_sec_value(mrb, sec));
    215299    /* not reached */
    216300    return NULL;
     
    229313}
    230314
    231 void mrb_check_num_exact(mrb_state *mrb, mrb_float num);
    232 
    233315/* Allocates a mrb_time object and initializes it. */
    234316static struct mrb_time*
    235 time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone)
    236 {
    237   struct mrb_time *tm;
    238   time_t tsec = 0;
    239 
    240   mrb_check_num_exact(mrb, (mrb_float)sec);
    241   mrb_check_num_exact(mrb, (mrb_float)usec);
    242 
    243   if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) {
    244     goto out_of_range;
    245   }
    246   if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) {
    247     goto out_of_range;
    248   }
    249   tsec  = (time_t)sec;
    250   if ((sec > 0 && tsec < 0) || (sec < 0 && (double)tsec > sec)) {
    251   out_of_range:
    252     mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec));
    253   }
     317time_alloc_time(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone timezone)
     318{
     319  struct mrb_time *tm;
     320
    254321  tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time));
    255   tm->sec  = tsec;
    256   tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec);
     322  tm->sec  = sec;
     323  tm->usec = usec;
    257324  if (tm->usec < 0) {
    258     long sec2 = (long)NDIV(usec,1000000); /* negative div */
     325    long sec2 = (long)NDIV(tm->usec,1000000); /* negative div */
    259326    tm->usec -= sec2 * 1000000;
    260327    tm->sec += sec2;
    261328  }
    262329  else if (tm->usec >= 1000000) {
    263     long sec2 = (long)(usec / 1000000);
     330    long sec2 = (long)(tm->usec / 1000000);
    264331    tm->usec -= sec2 * 1000000;
    265332    tm->sec += sec2;
    266333  }
    267334  tm->timezone = timezone;
    268   time_update_datetime(mrb, tm);
     335  time_update_datetime(mrb, tm, TRUE);
    269336
    270337  return tm;
    271338}
    272339
    273 static mrb_value
    274 mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mrb_timezone timezone)
     340static struct mrb_time*
     341time_alloc(mrb_state *mrb, mrb_value sec, mrb_value usec, enum mrb_timezone timezone)
     342{
     343  time_t tsec, tusec;
     344
     345  tsec = mrb_to_time_t(mrb, sec, &tusec);
     346  tusec += mrb_to_time_t(mrb, usec, NULL);
     347
     348  return time_alloc_time(mrb, tsec, tusec, timezone);
     349}
     350
     351static mrb_value
     352mrb_time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone)
     353{
     354  return mrb_time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone));
     355}
     356
     357static mrb_value
     358mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone)
    275359{
    276360  return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone));
     
    280364current_mrb_time(mrb_state *mrb)
    281365{
    282   struct mrb_time *tm;
    283 
    284   tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
    285 #if defined(TIME_UTC)
     366  struct mrb_time tmzero = {0};
     367  struct mrb_time *tm;
     368  time_t sec, usec;
     369
     370#if defined(TIME_UTC) && !defined(__ANDROID__)
    286371  {
    287372    struct timespec ts;
    288373    if (timespec_get(&ts, TIME_UTC) == 0) {
    289       mrb_free(mrb, tm);
    290374      mrb_raise(mrb, E_RUNTIME_ERROR, "timespec_get() failed for unknown reasons");
    291375    }
    292     tm->sec = ts.tv_sec;
    293     tm->usec = ts.tv_nsec / 1000;
     376    sec = ts.tv_sec;
     377    usec = ts.tv_nsec / 1000;
    294378  }
    295379#elif defined(NO_GETTIMEOFDAY)
     
    297381    static time_t last_sec = 0, last_usec = 0;
    298382
    299     tm->sec = time(NULL);
    300     if (tm->sec != last_sec) {
    301       last_sec = tm->sec;
     383    sec = time(NULL);
     384    if (sec != last_sec) {
     385      last_sec = sec;
    302386      last_usec = 0;
    303387    }
     
    306390      last_usec += 1;
    307391    }
    308     tm->usec = last_usec;
     392    usec = last_usec;
    309393  }
    310394#else
     
    313397
    314398    gettimeofday(&tv, NULL);
    315     tm->sec = tv.tv_sec;
    316     tm->usec = tv.tv_usec;
    317   }
    318 #endif
     399    sec = tv.tv_sec;
     400    usec = tv.tv_usec;
     401  }
     402#endif
     403  tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
     404  *tm = tmzero;
     405  tm->sec = sec; tm->usec = usec;
    319406  tm->timezone = MRB_TIMEZONE_LOCAL;
    320   time_update_datetime(mrb, tm);
     407  time_update_datetime(mrb, tm, TRUE);
    321408
    322409  return tm;
     
    328415{
    329416  return mrb_time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb));
     417}
     418
     419MRB_API mrb_value
     420mrb_time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone)
     421{
     422  return mrb_time_make_time(mrb, mrb_class_get(mrb, "Time"), sec, usec, zone);
    330423}
    331424
     
    333426/* Creates an instance of time at the given time in seconds, etc. */
    334427static mrb_value
    335 mrb_time_at(mrb_state *mrb, mrb_value self)
    336 {
    337   mrb_float f, f2 = 0;
    338 
    339   mrb_get_args(mrb, "f|f", &f, &f2);
    340   return mrb_time_make(mrb, mrb_class_ptr(self), f, f2, MRB_TIMEZONE_LOCAL);
     428mrb_time_at_m(mrb_state *mrb, mrb_value self)
     429{
     430  mrb_value sec;
     431  mrb_value usec = mrb_fixnum_value(0);
     432
     433  mrb_get_args(mrb, "o|o", &sec, &usec);
     434
     435  return mrb_time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL);
    341436}
    342437
     
    375470  }
    376471
    377   return time_alloc(mrb, (double)nowsecs, ausec, timezone);
     472  return time_alloc_time(mrb, nowsecs, ausec, timezone);
    378473}
    379474
     
    461556mrb_time_plus(mrb_state *mrb, mrb_value self)
    462557{
    463   mrb_float f;
    464   struct mrb_time *tm;
    465 
    466   mrb_get_args(mrb, "f", &f);
    467   tm = time_get_ptr(mrb, self);
    468   return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, (double)tm->usec, tm->timezone);
     558  mrb_value o;
     559  struct mrb_time *tm;
     560  time_t sec, usec;
     561
     562  mrb_get_args(mrb, "o", &o);
     563  tm = time_get_ptr(mrb, self);
     564  sec = mrb_to_time_t(mrb, o, &usec);
     565  return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), tm->sec+sec, tm->usec+usec, tm->timezone);
    469566}
    470567
     
    472569mrb_time_minus(mrb_state *mrb, mrb_value self)
    473570{
    474   mrb_float f;
    475571  mrb_value other;
    476572  struct mrb_time *tm, *tm2;
     
    480576  tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time);
    481577  if (tm2) {
    482     f = (mrb_float)(tm->sec - tm2->sec)
    483       + (mrb_float)(tm->usec - tm2->usec) / 1.0e6;
     578#ifndef MRB_WITHOUT_FLOAT
     579    mrb_float f;
     580    f = (mrb_sec)(tm->sec - tm2->sec)
     581      + (mrb_sec)(tm->usec - tm2->usec) / 1.0e6;
    484582    return mrb_float_value(mrb, f);
     583#else
     584    mrb_int f;
     585    f = tm->sec - tm2->sec;
     586    if (tm->usec < tm2->usec) f--;
     587    return mrb_fixnum_value(f);
     588#endif
    485589  }
    486590  else {
    487     mrb_get_args(mrb, "f", &f);
    488     return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, (double)tm->usec, tm->timezone);
     591    time_t sec, usec;
     592    sec = mrb_to_time_t(mrb, other, &usec);
     593    return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), tm->sec-sec, tm->usec-usec, tm->timezone);
    489594  }
    490595}
     
    547652  int len;
    548653
    549 #if defined(DISABLE_STDIO)
     654#if defined(MRB_DISABLE_STDIO)
    550655  char *s;
    551656# ifdef NO_ASCTIME_R
     
    559664  char buf[256];
    560665
    561   len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d",
     666  len = snprintf(buf, sizeof(buf), "%s %s %2d %02d:%02d:%02d %.4d",
    562667    wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
    563668    d->tm_hour, d->tm_min, d->tm_sec,
    564     tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "",
    565669    d->tm_year + 1900);
    566670#endif
     
    603707  *tm2 = *tm;
    604708  tm2->timezone = MRB_TIMEZONE_UTC;
    605   time_update_datetime(mrb, tm2);
     709  time_update_datetime(mrb, tm2, TRUE);
    606710  return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
    607711}
     
    618722  *tm2 = *tm;
    619723  tm2->timezone = MRB_TIMEZONE_LOCAL;
    620   time_update_datetime(mrb, tm2);
     724  time_update_datetime(mrb, tm2, TRUE);
    621725  return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
    622726}
     
    640744  mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0,
    641745  amin = 0, asec = 0, ausec = 0;
    642   int n;
     746  mrb_int n;
    643747  struct mrb_time *tm;
    644748
     
    696800  tm = time_get_ptr(mrb, self);
    697801  tm->timezone = MRB_TIMEZONE_LOCAL;
    698   time_update_datetime(mrb, tm);
     802  time_update_datetime(mrb, tm, FALSE);
    699803  return self;
    700804}
     
    744848}
    745849
    746 
     850#ifndef MRB_WITHOUT_FLOAT
    747851/* 15.2.19.7.24 */
    748852/* Returns a Float with the time since the epoch in seconds. */
     
    755859  return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6);
    756860}
     861#endif
    757862
    758863/* 15.2.19.7.25 */
    759 /* Returns a Fixnum with the time since the epoch in seconds. */
     864/* Returns an Integer with the time since the epoch in seconds. */
    760865static mrb_value
    761866mrb_time_to_i(mrb_state *mrb, mrb_value self)
     
    764869
    765870  tm = time_get_ptr(mrb, self);
    766   if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) {
     871#ifndef MRB_WITHOUT_FLOAT
     872  if (!fixable_time_t_p(tm->sec)) {
    767873    return mrb_float_value(mrb, (mrb_float)tm->sec);
    768874  }
     875#endif
    769876  return mrb_fixnum_value((mrb_int)tm->sec);
    770877}
    771878
    772879/* 15.2.19.7.26 */
    773 /* Returns a Float with the time since the epoch in microseconds. */
     880/* Returns an Integer with the time since the epoch in microseconds. */
    774881static mrb_value
    775882mrb_time_usec(mrb_state *mrb, mrb_value self)
     
    778885
    779886  tm = time_get_ptr(mrb, self);
    780   if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) {
     887#ifndef MRB_WITHOUT_FLOAT
     888  if (!fixable_time_t_p(tm->usec)) {
    781889    return mrb_float_value(mrb, (mrb_float)tm->usec);
    782890  }
     891#endif
    783892  return mrb_fixnum_value((mrb_int)tm->usec);
    784893}
     
    793902  tm = time_get_ptr(mrb, self);
    794903  tm->timezone = MRB_TIMEZONE_UTC;
    795   time_update_datetime(mrb, tm);
     904  time_update_datetime(mrb, tm, FALSE);
    796905  return self;
    797906}
     
    808917}
    809918
     919static size_t
     920time_to_s_utc(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len)
     921{
     922  return strftime(buf, buf_len, TO_S_FMT "UTC", &tm->datetime);
     923}
     924
     925static size_t
     926time_to_s_local(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len)
     927{
     928#if defined(_MSC_VER) && _MSC_VER < 1900 || defined(__MINGW64__) || defined(__MINGW32__)
     929  struct tm datetime = {0};
     930  time_t utc_sec = timegm(&tm->datetime);
     931  size_t len;
     932  int offset;
     933
     934  if (utc_sec == (time_t)-1) {
     935    mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time.");
     936  }
     937  offset = abs((int)(utc_sec - tm->sec) / 60);
     938  datetime.tm_year = 100;
     939  datetime.tm_hour = offset / 60;
     940  datetime.tm_min = offset % 60;
     941  len = strftime(buf, buf_len, TO_S_FMT, &tm->datetime);
     942  buf[len++] = utc_sec < tm->sec ? '-' : '+';
     943
     944  return len + strftime(buf + len, buf_len - len, "%H%M", &datetime);
     945#else
     946  return strftime(buf, buf_len, TO_S_FMT "%z", &tm->datetime);
     947#endif
     948}
     949
     950static mrb_value
     951mrb_time_to_s(mrb_state *mrb, mrb_value self)
     952{
     953  char buf[64];
     954  struct mrb_time *tm = time_get_ptr(mrb, self);
     955  mrb_bool utc = tm->timezone == MRB_TIMEZONE_UTC;
     956  size_t len = (utc ? time_to_s_utc : time_to_s_local)(mrb, tm, buf, sizeof(buf));
     957  return mrb_str_new(mrb, buf, len);
     958}
    810959
    811960void
     
    817966  MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA);
    818967  mrb_include_module(mrb, tc, mrb_module_get(mrb, "Comparable"));
    819   mrb_define_class_method(mrb, tc, "at", mrb_time_at, MRB_ARGS_ARG(1, 1));      /* 15.2.19.6.1 */
     968  mrb_define_class_method(mrb, tc, "at", mrb_time_at_m, MRB_ARGS_ARG(1, 1));      /* 15.2.19.6.1 */
    820969  mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, MRB_ARGS_ARG(1,6));       /* 15.2.19.6.2 */
    821970  mrb_define_class_method(mrb, tc, "local", mrb_time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */
     
    828977  mrb_define_method(mrb, tc, "+"      , mrb_time_plus   , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */
    829978  mrb_define_method(mrb, tc, "-"      , mrb_time_minus  , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */
    830   mrb_define_method(mrb, tc, "to_s"   , mrb_time_asctime, MRB_ARGS_NONE());
    831   mrb_define_method(mrb, tc, "inspect", mrb_time_asctime, MRB_ARGS_NONE());
     979  mrb_define_method(mrb, tc, "to_s"   , mrb_time_to_s   , MRB_ARGS_NONE());
     980  mrb_define_method(mrb, tc, "inspect", mrb_time_to_s   , MRB_ARGS_NONE());
    832981  mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */
    833982  mrb_define_method(mrb, tc, "ctime"  , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */
     
    849998  mrb_define_method(mrb, tc, "sec" , mrb_time_sec, MRB_ARGS_NONE());        /* 15.2.19.7.23 */
    850999  mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, MRB_ARGS_NONE());       /* 15.2.19.7.25 */
     1000#ifndef MRB_WITHOUT_FLOAT
    8511001  mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, MRB_ARGS_NONE());       /* 15.2.19.7.24 */
     1002#endif
    8521003  mrb_define_method(mrb, tc, "usec", mrb_time_usec, MRB_ARGS_NONE());       /* 15.2.19.7.26 */
    8531004  mrb_define_method(mrb, tc, "utc" , mrb_time_utc, MRB_ARGS_NONE());        /* 15.2.19.7.27 */
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-time/test/time.rb

    r331 r439  
    33
    44assert('Time.new', '15.2.3.3.3') do
    5   Time.new.class == Time
     5  assert_equal(Time, Time.new.class)
    66end
    77
    88assert('Time', '15.2.19') do
    9   Time.class == Class
     9  assert_equal(Class, Time.class)
    1010end
    1111
     
    2222
    2323assert('Time.gm', '15.2.19.6.2') do
    24   Time.gm(2012, 12, 23)
     24  t = Time.gm(2012, 9, 23)
     25  assert_operator(2012, :eql?, t.year)
     26  assert_operator(   9, :eql?, t.month)
     27  assert_operator(  23, :eql?, t.day)
     28  assert_operator(   0, :eql?, t.hour)
     29  assert_operator(   0, :eql?, t.min)
     30  assert_operator(   0, :eql?, t.sec)
     31  assert_operator(   0, :eql?, t.usec)
    2532end
    2633
    2734assert('Time.local', '15.2.19.6.3') do
    28   Time.local(2012, 12, 23)
     35  t = Time.local(2014, 12, 27, 18)
     36  assert_operator(2014, :eql?, t.year)
     37  assert_operator(  12, :eql?, t.month)
     38  assert_operator(  27, :eql?, t.day)
     39  assert_operator(  18, :eql?, t.hour)
     40  assert_operator(   0, :eql?, t.min)
     41  assert_operator(   0, :eql?, t.sec)
     42  assert_operator(   0, :eql?, t.usec)
    2943end
    3044
    3145assert('Time.mktime', '15.2.19.6.4') do
    32   Time.mktime(2012, 12, 23)
     46  t = Time.mktime(2013, 10, 4, 6, 15, 58, 3485)
     47  assert_operator(2013, :eql?, t.year)
     48  assert_operator(  10, :eql?, t.month)
     49  assert_operator(   4, :eql?, t.day)
     50  assert_operator(   6, :eql?, t.hour)
     51  assert_operator(  15, :eql?, t.min)
     52  assert_operator(  58, :eql?, t.sec)
     53  assert_operator(3485, :eql?, t.usec)
    3354end
    3455
    3556assert('Time.now', '15.2.19.6.5') do
    36   Time.now.class == Time
     57  assert_equal(Time, Time.now.class)
    3758end
    3859
    3960assert('Time.utc', '15.2.19.6.6') do
    40   Time.utc(2012, 12, 23)
     61  t = Time.utc(2034)
     62  assert_operator(2034, :eql?, t.year)
     63  assert_operator(   1, :eql?, t.month)
     64  assert_operator(   1, :eql?, t.day)
     65  assert_operator(   0, :eql?, t.hour)
     66  assert_operator(   0, :eql?, t.min)
     67  assert_operator(   0, :eql?, t.sec)
     68  assert_operator(   0, :eql?, t.usec)
    4169end
    4270
     
    4573  t2 = t1.+(60)
    4674
    47   assert_equal(t2.utc.asctime, "Sun Mar 13 07:07:40 UTC 2011")
     75  assert_equal("Sun Mar 13 07:07:40 2011", t2.utc.asctime)
    4876
    4977  assert_raise(FloatDomainError) { Time.at(0) + Float::NAN }
     
    5684  t2 = t1.-(60)
    5785
    58   assert_equal(t2.utc.asctime, "Sun Mar 13 07:05:40 UTC 2011")
     86  assert_equal("Sun Mar 13 07:05:40 2011", t2.utc.asctime)
    5987
    6088  assert_raise(FloatDomainError) { Time.at(0) - Float::NAN }
     
    6896  t3 = Time.at(1500000000.0)
    6997
    70   t2.<=>(t1) == 1 and
    71     t2.<=>(t2) == 0 and
    72     t2.<=>(t3) == -1 and
    73     t2.<=>(nil) == nil
     98  assert_equal(1, t2 <=> t1)
     99  assert_equal(0, t2 <=> t2)
     100  assert_equal(-1, t2 <=> t3)
     101  assert_nil(t2 <=> nil)
    74102end
    75103
    76104assert('Time#asctime', '15.2.19.7.4') do
    77   Time.at(1300000000.0).utc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
     105  assert_equal("Thu Mar  4 05:06:07 1982", Time.gm(1982,3,4,5,6,7).asctime)
    78106end
    79107
    80108assert('Time#ctime', '15.2.19.7.5') do
    81   Time.at(1300000000.0).utc.ctime == "Sun Mar 13 07:06:40 UTC 2011"
     109  assert_equal("Thu Oct 24 15:26:47 2013", Time.gm(2013,10,24,15,26,47).ctime)
    82110end
    83111
    84112assert('Time#day', '15.2.19.7.6') do
    85   Time.gm(2012, 12, 23).day == 23
     113  assert_equal(23, Time.gm(2012, 12, 23).day)
    86114end
    87115
    88116assert('Time#dst?', '15.2.19.7.7') do
    89   not Time.gm(2012, 12, 23).utc.dst?
     117  assert_not_predicate(Time.gm(2012, 12, 23).utc, :dst?)
    90118end
    91119
    92120assert('Time#getgm', '15.2.19.7.8') do
    93   Time.at(1300000000.0).getgm.asctime == "Sun Mar 13 07:06:40 UTC 2011"
     121  assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getgm.asctime)
    94122end
    95123
     
    99127  t3 = t1.getlocal
    100128
    101   t1 == t3 and t3 == t2.getlocal
     129  assert_equal(t1, t3)
     130  assert_equal(t3, t2.getlocal)
    102131end
    103132
    104133assert('Time#getutc', '15.2.19.7.10') do
    105   Time.at(1300000000.0).getutc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
     134  assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getutc.asctime)
    106135end
    107136
    108137assert('Time#gmt?', '15.2.19.7.11') do
    109   Time.at(1300000000.0).utc.gmt?
     138  assert_predicate(Time.at(1300000000.0).utc, :gmt?)
    110139end
    111140
     
    114143
    115144assert('Time#gmtime', '15.2.19.7.13') do
    116   Time.at(1300000000.0).gmtime
     145  t = Time.now
     146  assert_predicate(t.gmtime, :gmt?)
     147  assert_predicate(t, :gmt?)
    117148end
    118149
     
    121152
    122153assert('Time#hour', '15.2.19.7.15') do
    123   Time.gm(2012, 12, 23, 7, 6).hour == 7
     154  assert_equal(7, Time.gm(2012, 12, 23, 7, 6).hour)
    124155end
    125156
     
    128159
    129160assert('Time#initialize_copy', '15.2.19.7.17') do
    130   time_tmp_2 = Time.at(7.0e6)
    131   time_tmp_2.clone == time_tmp_2
     161  t = Time.at(7.0e6)
     162  assert_equal(t, t.clone)
    132163end
    133164
    134165assert('Time#localtime', '15.2.19.7.18') do
    135   t1 = Time.at(1300000000.0)
    136   t2 = Time.at(1300000000.0)
    137 
    138   t1.localtime
    139   t1 == t2.getlocal
     166  t1 = Time.utc(2014, 5 ,6)
     167  t2 = Time.utc(2014, 5 ,6)
     168  t3 = t2.getlocal
     169
     170  assert_equal(t3, t1.localtime)
     171  assert_equal(t3, t1)
    140172end
    141173
    142174assert('Time#mday', '15.2.19.7.19') do
    143   Time.gm(2012, 12, 23).mday == 23
     175  assert_equal(23, Time.gm(2012, 12, 23).mday)
    144176end
    145177
    146178assert('Time#min', '15.2.19.7.20') do
    147   Time.gm(2012, 12, 23, 7, 6).min == 6
     179  assert_equal(6, Time.gm(2012, 12, 23, 7, 6).min)
    148180end
    149181
    150182assert('Time#mon', '15.2.19.7.21') do
    151   Time.gm(2012, 12, 23).mon == 12
     183  assert_equal(12, Time.gm(2012, 12, 23).mon)
    152184end
    153185
    154186assert('Time#month', '15.2.19.7.22') do
    155   Time.gm(2012, 12, 23).month == 12
     187  assert_equal(12, Time.gm(2012, 12, 23).month)
    156188end
    157189
    158190assert('Times#sec', '15.2.19.7.23') do
    159   Time.gm(2012, 12, 23, 7, 6, 40).sec == 40
     191  assert_equal(40, Time.gm(2012, 12, 23, 7, 6, 40).sec)
    160192end
    161193
    162194assert('Time#to_f', '15.2.19.7.24') do
    163   Time.at(1300000000.0).to_f == 1300000000.0
     195  assert_operator(2.0, :eql?, Time.at(2).to_f)
    164196end
    165197
    166198assert('Time#to_i', '15.2.19.7.25') do
    167   Time.at(1300000000.0).to_i == 1300000000
     199  assert_operator(2, :eql?, Time.at(2.0).to_i)
    168200end
    169201
    170202assert('Time#usec', '15.2.19.7.26') do
    171   Time.at(1300000000.0).usec == 0
     203  assert_equal(0, Time.at(1300000000.0).usec)
    172204end
    173205
    174206assert('Time#utc', '15.2.19.7.27') do
    175   Time.at(1300000000.0).utc
     207  t = Time.now
     208  assert_predicate(t.utc, :gmt?)
     209  assert_predicate(t, :gmt?)
    176210end
    177211
    178212assert('Time#utc?', '15.2.19.7.28') do
    179   Time.at(1300000000.0).utc.utc?
     213  assert_predicate(Time.at(1300000000.0).utc, :utc?)
    180214end
    181215
     
    184218
    185219assert('Time#wday', '15.2.19.7.30') do
    186   Time.gm(2012, 12, 23).wday == 0
     220  assert_equal(0, Time.gm(2012, 12, 23).wday)
    187221end
    188222
    189223assert('Time#yday', '15.2.19.7.31') do
    190   Time.gm(2012, 12, 23).yday == 358
     224  assert_equal(358, Time.gm(2012, 12, 23).yday)
    191225end
    192226
    193227assert('Time#year', '15.2.19.7.32') do
    194   Time.gm(2012, 12, 23).year == 2012
     228  assert_equal(2012, Time.gm(2012, 12, 23).year)
    195229end
    196230
    197231assert('Time#zone', '15.2.19.7.33') do
    198   Time.at(1300000000.0).utc.zone == 'UTC'
     232  assert_equal('UTC', Time.at(1300000000.0).utc.zone)
    199233end
    200234
     
    202236
    203237assert('Time#to_s') do
    204   Time.at(1300000000.0).utc.to_s == "Sun Mar 13 07:06:40 UTC 2011"
     238  assert_equal("2003-04-05 06:07:08 UTC", Time.gm(2003,4,5,6,7,8,9).to_s)
    205239end
    206240
    207241assert('Time#inspect') do
    208   Time.at(1300000000.0).utc.inspect == "Sun Mar 13 07:06:40 UTC 2011"
     242  assert_match("2013-10-28 16:27:48 [+-][0-9][0-9][0-9][0-9]",
     243               Time.local(2013,10,28,16,27,48).inspect)
    209244end
    210245
     
    225260    t += 0.0005
    226261  end
    227   t.usec == 0
    228 end
     262  assert_equal(0, t.usec)
     263end
     264
     265assert('Time.gm with Dec 31 23:59:59 1969 raise ArgumentError') do
     266  assert_raise(ArgumentError) {Time.gm(1969, 12, 31, 23, 59, 59)}
     267end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-toplevel-ext/test/toplevel.rb

    r321 r439  
    1717  self.include ToplevelTestModule2, ToplevelTestModule1
    1818
    19   assert_true self.class.included_modules.include?( ToplevelTestModule1 )
    20   assert_true self.class.included_modules.include?( ToplevelTestModule2 )
     19  assert_true self.class.ancestors.include?( ToplevelTestModule1 )
     20  assert_true self.class.ancestors.include?( ToplevelTestModule2 )
    2121  assert_equal :foo, method_foo
    2222  assert_equal :bar2, CONST_BAR
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/00class.rb

    r331 r439  
    66  end
    77  # 15.2.2.4.11
    8   def attr(name)
    9     attr_reader(name)
    10   end
     8  alias attr attr_reader
     9  #def attr(name)
     10  #  attr_reader(name)
     11  #end
    1112
    1213  # 15.2.2.4.27
     
    1617      m.included(self)
    1718    end
     19    self
    1820  end
    1921
     
    2325      m.prepended(self)
    2426    end
     27    self
    2528  end
    2629end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/10error.rb

    r331 r439  
    33end
    44
    5 # ISO 15.2.25
    6 class LocalJumpError < StandardError
     5# ISO 15.2.25 says "LocalJumpError < StandardError"
     6class LocalJumpError < ScriptError
    77end
    88
     
    5252end
    5353
     54class FrozenError < RuntimeError
     55end
     56
    5457class StopIteration < IndexError
    5558  attr_accessor :result
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/array.rb

    r331 r439  
     1# coding: utf-8
    12##
    23# Array
     
    1011  #
    1112  # ISO 15.2.12.5.10
    12   def each(&block)
    13     return to_enum :each unless block_given?
    14 
    15     idx = 0
    16     while idx < length
    17       block.call(self[idx])
    18       idx += 1
    19     end
    20     self
    21   end
     13  # def each(&block)
     14  #   return to_enum :each unless block
     15
     16  #   idx = 0
     17  #   while idx < length
     18  #     block.call(self[idx])
     19  #     idx += 1
     20  #   end
     21  #   self
     22  # end
    2223
    2324  ##
     
    2728  # ISO 15.2.12.5.11
    2829  def each_index(&block)
    29     return to_enum :each_index unless block_given?
     30    return to_enum :each_index unless block
    3031
    3132    idx = 0
     
    4445  # ISO 15.2.12.5.7
    4546  def collect!(&block)
    46     return to_enum :collect! unless block_given?
    47 
    48     self.each_index { |idx| self[idx] = block.call(self[idx]) }
     47    return to_enum :collect! unless block
     48
     49    idx = 0
     50    len = size
     51    while idx < len
     52      self[idx] = block.call self[idx]
     53      idx += 1
     54    end
    4955    self
    5056  end
     
    6167  # ISO 15.2.12.5.15
    6268  def initialize(size=0, obj=nil, &block)
    63     raise TypeError, "expected Integer for 1st argument" unless size.kind_of? Integer
     69    size = size.__to_int
    6470    raise ArgumentError, "negative array size" if size < 0
    6571
     
    7884  end
    7985
    80   def _inspect
    81     return "[]" if self.size == 0
    82     "["+self.map{|x|x.inspect}.join(", ")+"]"
     86  def _inspect(recur_list)
     87    size = self.size
     88    return "[]" if size == 0
     89    return "[...]" if recur_list[self.object_id]
     90    recur_list[self.object_id] = true
     91    ary=[]
     92    i=0
     93    while i<size
     94      ary<<self[i]._inspect(recur_list)
     95      i+=1
     96    end
     97    "["+ary.join(", ")+"]"
    8398  end
    8499  ##
     
    87102  # ISO 15.2.12.5.31 (x)
    88103  def inspect
    89     begin
    90       self._inspect
    91     rescue SystemStackError
    92       "[...]"
    93     end
     104    self._inspect({})
    94105  end
    95106  # ISO 15.2.12.5.32 (x)
     
    179190    ret
    180191  end
    181 
    182   # internal method to convert multi-value to single value
    183   def __svalue
    184     return self.first if self.size < 2
    185     self
    186   end
    187192end
    188193
     
    197202  # elements.
    198203  def sort!(&block)
    199     self.replace(self.sort(&block))
     204    stack = [ [ 0, self.size - 1 ] ]
     205    until stack.empty?
     206      left, mid, right = stack.pop
     207      if right == nil
     208        right = mid
     209        # sort self[left..right]
     210        if left < right
     211          if left + 1 == right
     212            lval = self[left]
     213            rval = self[right]
     214            cmp = if block then block.call(lval,rval) else lval <=> rval end
     215            if cmp.nil?
     216              raise ArgumentError, "comparison of #{lval.inspect} and #{rval.inspect} failed"
     217            end
     218            if cmp > 0
     219              self[left]  = rval
     220              self[right] = lval
     221            end
     222          else
     223            mid = ((left + right + 1) / 2).floor
     224            stack.push [ left, mid, right ]
     225            stack.push [ mid, right ]
     226            stack.push [ left, (mid - 1) ] if left < mid - 1
     227          end
     228        end
     229      else
     230        lary = self[left, mid - left]
     231        lsize = lary.size
     232
     233        # The entity sharing between lary and self may cause a large memory
     234        # copy operation in the merge loop below.  This harmless operation
     235        # cancels the sharing and provides a huge performance gain.
     236        lary[0] = lary[0]
     237
     238        # merge
     239        lidx = 0
     240        ridx = mid
     241        (left..right).each { |i|
     242          if lidx >= lsize
     243            break
     244          elsif ridx > right
     245            self[i, lsize - lidx] = lary[lidx, lsize - lidx]
     246            break
     247          else
     248            lval = lary[lidx]
     249            rval = self[ridx]
     250            cmp = if block then block.call(lval,rval) else lval <=> rval end
     251            if cmp.nil?
     252              raise ArgumentError, "comparison of #{lval.inspect} and #{rval.inspect} failed"
     253            end
     254            if cmp <= 0
     255              self[i] = lval
     256              lidx += 1
     257            else
     258              self[i] = rval
     259              ridx += 1
     260            end
     261          end
     262        }
     263      end
     264    end
     265    self
     266  end
     267
     268  def sort(&block)
     269    self.dup.sort!(&block)
    200270  end
    201271end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/enum.rb

    r331 r439  
    1414module Enumerable
    1515
     16  NONE = Object.new
     17
    1618  ##
    1719  # Call the given block for each element
     
    6466
    6567  ##
    66   # Call the given block for each element
    67   # which is yield by +each+. Return
    68   # +ifnone+ if no block value was true.
    69   # Otherwise return the first block value
    70   # which had was true.
     68  # Return the first element for which
     69  # value from the block is true. If no
     70  # object matches, calls +ifnone+ and
     71  # returns its result. Otherwise returns
     72  # +nil+.
    7173  #
    7274  # ISO 15.3.2.2.4
    7375  def detect(ifnone=nil, &block)
    74     ret = ifnone
     76    return to_enum :detect, ifnone unless block
     77
    7578    self.each{|*val|
    7679      if block.call(*val)
    77         ret = val.__svalue
    78         break
    79       end
    80     }
    81     ret
     80        return val.__svalue
     81      end
     82    }
     83    ifnone.call unless ifnone.nil?
    8284  end
    8385
     
    283285  # ISO 15.3.2.2.16
    284286  def partition(&block)
     287    return to_enum :partition unless block
     288
    285289    ary_T = []
    286290    ary_F = []
     
    303307  # ISO 15.3.2.2.17
    304308  def reject(&block)
     309    return to_enum :reject unless block
     310
    305311    ary = []
    306312    self.each{|*val|
     
    315321  # ISO 15.3.2.2.18
    316322  alias select find_all
    317 
    318   ##
    319   # TODO
    320   # Does this OK? Please test it.
    321   def __sort_sub__(sorted, work, src_ary, head, tail, &block)
    322     if head == tail
    323       sorted[head] = work[head] if src_ary == 1
    324       return
    325     end
    326 
    327     # on current step, which is a src ary?
    328     if src_ary == 0
    329       src, dst = sorted, work
    330     else
    331       src, dst = work, sorted
    332     end
    333 
    334     key = src[head]    # key value for dividing values
    335     i, j = head, tail  # position to store on the dst ary
    336 
    337     (head + 1).upto(tail){|idx|
    338       if ((block)? block.call(src[idx], key): (src[idx] <=> key)) > 0
    339         # larger than key
    340         dst[j] = src[idx]
    341         j -= 1
    342       else
    343         dst[i] = src[idx]
    344         i += 1
    345       end
    346     }
    347 
    348     sorted[i] = key
    349 
    350     # sort each sub-array
    351     src_ary = (src_ary + 1) % 2  # exchange a src ary
    352     __sort_sub__(sorted, work, src_ary, head, i - 1, &block) if i > head
    353     __sort_sub__(sorted, work, src_ary, i + 1, tail, &block) if i < tail
    354   end
    355 #  private :__sort_sub__
    356323
    357324  ##
     
    365332  # ISO 15.3.2.2.19
    366333  def sort(&block)
    367     ary = []
    368     self.each{|*val| ary.push(val.__svalue)}
    369     if ary.size > 1
    370       __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1, &block)
    371     end
    372     ary
     334    self.map{|*val| val.__svalue}.sort(&block)
    373335  end
    374336
     
    384346    i = 0
    385347    self.each do |e|
    386       n = (e.hash & (0x7fffffff >> (i % 16))) << (i % 16)
    387       h ^= n
     348      h = __update_hash(h, i, e.hash)
    388349      i += 1
    389350    end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/hash.rb

    r331 r439  
    1313  def ==(hash)
    1414    return true if self.equal?(hash)
    15     begin
    16       hash = hash.to_hash
    17     rescue NoMethodError
     15    unless Hash === hash
    1816      return false
    1917    end
     
    3331  def eql?(hash)
    3432    return true if self.equal?(hash)
    35     begin
    36       hash = hash.to_hash
    37     rescue NoMethodError
     33    unless Hash === hash
    3834      return false
    3935    end
     
    5652  def delete(key, &block)
    5753    if block && !self.has_key?(key)
    58       block.call(key)
    59     else
    60       self.__delete(key)
    61     end
     54      return block.call(key)
     55    end
     56    self.__delete(key)
    6257  end
    6358
     
    8580  # ISO 15.2.13.4.9
    8681  def each(&block)
    87     return to_enum :each unless block_given?
     82    return to_enum :each unless block
    8883
    8984    keys = self.keys
     
    118113  # ISO 15.2.13.4.10
    119114  def each_key(&block)
    120     return to_enum :each_key unless block_given?
     115    return to_enum :each_key unless block
    121116
    122117    self.keys.each{|k| block.call(k)}
     
    144139  # ISO 15.2.13.4.11
    145140  def each_value(&block)
    146     return to_enum :each_value unless block_given?
     141    return to_enum :each_value unless block
    147142
    148143    self.keys.each{|k| block.call(self[k])}
     
    155150  # ISO 15.2.13.4.23
    156151  def replace(hash)
    157     raise TypeError, "can't convert argument into Hash" unless hash.respond_to?(:to_hash)
     152    raise TypeError, "Hash required (#{hash.class} given)" unless Hash === hash
    158153    self.clear
    159     hash = hash.to_hash
    160154    hash.each_key{|k|
    161155      self[k] = hash[k]
     
    180174  # ISO 15.2.13.4.22
    181175  def merge(other, &block)
    182     h = {}
    183     raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash)
    184     other = other.to_hash
    185     self.each_key{|k| h[k] = self[k]}
     176    raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
     177    h = self.dup
    186178    if block
    187179      other.each_key{|k|
     
    195187
    196188  # internal method for Hash inspection
    197   def _inspect
     189  def _inspect(recur_list)
    198190    return "{}" if self.size == 0
    199     "{"+self.map {|k,v|
    200       k._inspect + "=>" + v._inspect
    201     }.join(", ")+"}"
     191    return "{...}" if recur_list[self.object_id]
     192    recur_list[self.object_id] = true
     193    ary=[]
     194    keys=self.keys
     195    size=keys.size
     196    i=0
     197    while i<size
     198      k=keys[i]
     199      ary<<(k._inspect(recur_list) + "=>" + self[k]._inspect(recur_list))
     200      i+=1
     201    end
     202    "{"+ary.join(", ")+"}"
    202203  end
    203204  ##
     
    206207  # ISO 15.2.13.4.30 (x)
    207208  def inspect
    208     begin
    209       self._inspect
    210     rescue SystemStackError
    211       "{...}"
    212     end
     209    self._inspect({})
    213210  end
    214211  # ISO 15.2.13.4.31 (x)
     
    225222  #  1.8/1.9 Hash#reject! returns Hash; ISO says nothing.
    226223  #
    227   def reject!(&b)
    228     return to_enum :reject! unless block_given?
     224  def reject!(&block)
     225    return to_enum :reject! unless block
    229226
    230227    keys = []
    231228    self.each{|k,v|
    232       if b.call([k, v])
     229      if block.call([k, v])
    233230        keys.push(k)
    234231      end
     
    256253  #  1.8/1.9 Hash#reject returns Hash; ISO says nothing.
    257254  #
    258   def reject(&b)
    259     return to_enum :reject unless block_given?
     255  def reject(&block)
     256    return to_enum :reject unless block
    260257
    261258    h = {}
    262259    self.each{|k,v|
    263       unless b.call([k, v])
     260      unless block.call([k, v])
    264261        h[k] = v
    265262      end
     
    278275  #  1.9 Hash#select! returns Hash; ISO says nothing.
    279276  #
    280   def select!(&b)
    281     return to_enum :select! unless block_given?
     277  def select!(&block)
     278    return to_enum :select! unless block
    282279
    283280    keys = []
    284281    self.each{|k,v|
    285       unless b.call([k, v])
     282      unless block.call([k, v])
    286283        keys.push(k)
    287284      end
     
    309306  #  1.9 Hash#select returns Hash; ISO says nothing
    310307  #
    311   def select(&b)
    312     return to_enum :select unless block_given?
     308  def select(&block)
     309    return to_enum :select unless block
    313310
    314311    h = {}
    315312    self.each{|k,v|
    316       if b.call([k, v])
     313      if block.call([k, v])
    317314        h[k] = v
    318315      end
    319316    }
    320317    h
    321   end
    322 
    323   ##
    324   #  call-seq:
    325   #    hsh.rehash -> hsh
    326   #
    327   #  Rebuilds the hash based on the current hash values for each key. If
    328   #  values of key objects have changed since they were inserted, this
    329   #  method will reindex <i>hsh</i>.
    330   #
    331   #     h = {"AAA" => "b"}
    332   #     h.keys[0].chop!
    333   #     h          #=> {"AA"=>"b"}
    334   #     h["AA"]    #=> nil
    335   #     h.rehash   #=> {"AA"=>"b"}
    336   #     h["AA"]    #=> "b"
    337   #
    338   def rehash
    339     h = {}
    340     self.each{|k,v|
    341       h[k] = v
    342     }
    343     self.replace(h)
    344   end
    345 
    346   def __update(h)
    347     h.each_key{|k| self[k] = h[k]}
    348     self
    349318  end
    350319end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/kernel.rb

    r321 r439  
    77  # 15.3.1.2.1 Kernel.`
    88  # provided by Kernel#`
    9   # 15.3.1.3.5
     9  # 15.3.1.3.3
    1010  def `(s)
    1111    raise NotImplementedError.new("backquotes not implemented")
     
    4141
    4242  # internal method for inspect
    43   def _inspect
     43  def _inspect(_recur_list)
    4444    self.inspect
    4545  end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/mrblib.rake

    r321 r439  
    44  current_build_dir = "#{build_dir}/#{relative_from_root}"
    55
    6   self.libmruby << objfile("#{current_build_dir}/mrblib")
     6  self.libmruby_objs << objfile("#{current_build_dir}/mrblib")
    77
    88  file objfile("#{current_build_dir}/mrblib") => "#{current_build_dir}/mrblib.c"
    99  file "#{current_build_dir}/mrblib.c" => [mrbcfile, __FILE__] + Dir.glob("#{current_dir}/*.rb").sort do |t|
    1010    _, _, *rbfiles = t.prerequisites
    11     FileUtils.mkdir_p File.dirname(t.name)
     11    mkdir_p File.dirname(t.name)
    1212    open(t.name, 'w') do |f|
    1313      _pp "GEN", "*.rb", "#{t.name.relative_path}"
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/numeric.rb

    r331 r439  
    4646  # ISO 15.2.8.3.15
    4747  def downto(num, &block)
    48     return to_enum(:downto, num) unless block_given?
     48    return to_enum(:downto, num) unless block
    4949
    5050    i = self.to_i
     
    7171  # ISO 15.2.8.3.22
    7272  def times &block
    73     return to_enum :times unless block_given?
     73    return to_enum :times unless block
    7474
    7575    i = 0
     
    8787  # ISO 15.2.8.3.27
    8888  def upto(num, &block)
    89     return to_enum(:upto, num) unless block_given?
     89    return to_enum(:upto, num) unless block
    9090
    9191    i = self.to_i
     
    103103  def step(num=nil, step=1, &block)
    104104    raise ArgumentError, "step can't be 0" if step == 0
    105     return to_enum(:step, num, step) unless block_given?
     105    return to_enum(:step, num, step) unless block
    106106
    107     i = if num.kind_of? Float then self.to_f else self end
    108     if num == nil
     107    i = __coerce_step_counter(num, step)
     108    if num == self || step.infinite?
     109      block.call(i) if step > 0 && i <= (num||i) || step < 0 && i >= (num||-i)
     110    elsif num == nil
    109111      while true
    110112        block.call(i)
    111         i+=step
     113        i += step
    112114      end
    113       return self
    114     end
    115     if step > 0
     115    elsif step > 0
    116116      while i <= num
    117117        block.call(i)
     
    162162  alias truncate floor
    163163end
    164 
    165 ##
    166 # Float
    167 #
    168 # ISO 15.2.9
    169 class Float
    170   # mruby special - since mruby integers may be upgraded to floats,
    171   # floats should be compatible to integers.
    172   include Integral
    173 end
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/range.rb

    r331 r439  
    1111  # ISO 15.2.14.4.4
    1212  def each(&block)
    13     return to_enum :each unless block_given?
     13    return to_enum :each unless block
    1414
    1515    val = self.first
     
    2727    end
    2828
    29     if val.kind_of?(String) && last.kind_of?(String) # fixnums are special
     29    if val.kind_of?(String) && last.kind_of?(String) # strings are special
    3030      if val.respond_to? :upto
    3131        return val.upto(last, exclude_end?, &block)
  • EcnlProtoTool/trunk/mruby-2.1.1/mrblib/string.rb

    r331 r439  
    44# ISO 15.2.10
    55class String
     6  # ISO 15.2.10.3
    67  include Comparable
     8
    79  ##
    810  # Calls the given block for each line
     
    1012  #
    1113  # ISO 15.2.10.5.15
    12   def each_line(rs = "\n", &block)
    13     return to_enum(:each_line, rs, &block) unless block
    14     return block.call(self) if rs.nil?
    15     rs = rs.to_str
    16     offset = 0
    17     rs_len = rs.length
    18     this = dup
    19     while pos = this.index(rs, offset)
    20       block.call(this[offset, pos + rs_len - offset])
    21       offset = pos + rs_len
    22     end
    23     block.call(this[offset, this.size - offset]) if this.size > offset
     14  def each_line(separator = "\n", &block)
     15    return to_enum(:each_line, separator) unless block
     16
     17    if separator.nil?
     18      block.call(self)
     19      return self
     20    end
     21    raise TypeError unless separator.is_a?(String)
     22
     23    paragraph_mode = false
     24    if separator.empty?
     25      paragraph_mode = true
     26      separator = "\n\n"
     27    end
     28    start = 0
     29    string = dup
     30    self_len = length
     31    sep_len = separator.length
     32    should_yield_subclass_instances = self.class != String
     33
     34    while (pointer = string.index(separator, start))
     35      pointer += sep_len
     36      pointer += 1 while paragraph_mode && string[pointer] == "\n"
     37      if should_yield_subclass_instances
     38        block.call(self.class.new(string[start, pointer - start]))
     39      else
     40        block.call(string[start, pointer - start])
     41      end
     42      start = pointer
     43    end
     44    return self if start == self_len
     45
     46    if should_yield_subclass_instances
     47      block.call(self.class.new(string[start, self_len - start]))
     48    else
     49      block.call(string[start, self_len - start])
     50    end
    2451    self
    2552  end
     
    6895    end
    6996    if !replace.nil? || !block
    70       replace = replace.to_str
     97      replace.__to_str
    7198    end
    7299    offset = 0
     
    97124  # ISO 15.2.10.5.19
    98125  def gsub!(*args, &block)
    99     raise RuntimeError, "can't modify frozen String" if frozen?
     126    raise FrozenError, "can't modify frozen String" if frozen?
    100127    return to_enum(:gsub!, *args) if args.length == 1 && !block
    101128    str = self.gsub(*args, &block)
    102     return nil if str == self
     129    return nil unless self.index(args[0])
    103130    self.replace(str)
    104131  end
    105132
    106   ##
    107   # Calls the given block for each match of +pattern+
    108   # If no block is given return an array with all
    109   # matches of +pattern+.
    110   #
    111   # ISO 15.2.10.5.32
    112   def scan(reg, &block)
    113     ### *** TODO *** ###
    114     unless Object.const_defined?(:Regexp)
    115       raise NotImplementedError, "scan not available (yet)"
    116     end
    117   end
     133#  ##
     134#  # Calls the given block for each match of +pattern+
     135#  # If no block is given return an array with all
     136#  # matches of +pattern+.
     137  ##
     138#  # ISO 15.2.10.5.32
     139#  def scan(pattern, &block)
     140#    # TODO: String#scan is not implemented yet
     141#  end
    118142
    119143  ##
     
    130154
    131155    pattern, replace = *args
    132     pattern = pattern.to_str
     156    pattern.__to_str
    133157    if args.length == 2 && block
    134158      block = nil
    135159    end
    136     if !block
    137       replace = replace.to_str
     160    unless block
     161      replace.__to_str
    138162    end
    139163    result = []
     
    160184  # ISO 15.2.10.5.37
    161185  def sub!(*args, &block)
    162     raise RuntimeError, "can't modify frozen String" if frozen?
     186    raise FrozenError, "can't modify frozen String" if frozen?
    163187    str = self.sub(*args, &block)
    164     return nil if str == self
     188    return nil unless self.index(args[0])
    165189    self.replace(str)
    166   end
    167 
    168   ##
    169   # Call the given block for each character of
    170   # +self+.
    171   def each_char(&block)
    172     pos = 0
    173     while pos < self.size
    174       block.call(self[pos])
    175       pos += 1
    176     end
    177     self
    178190  end
    179191
     
    181193  # Call the given block for each byte of +self+.
    182194  def each_byte(&block)
     195    return to_enum(:each_byte, &block) unless block
    183196    bytes = self.bytes
    184197    pos = 0
     
    190203  end
    191204
    192   ##
    193   # Modify +self+ by replacing the content of +self+.
    194   # The portion of the string affected is determined using the same criteria as +String#[]+.
    195   def []=(*args)
    196     anum = args.size
    197     if anum == 2
    198       pos, value = args
    199       case pos
    200       when String
    201         posnum = self.index(pos)
    202         if posnum
    203           b = self[0, posnum.to_i]
    204           a = self[(posnum + pos.length)..-1]
    205           self.replace([b, value, a].join(''))
    206         else
    207           raise IndexError, "string not matched"
    208         end
    209       when Range
    210         head = pos.begin
    211         tail = pos.end
    212         tail += self.length if tail < 0
    213         unless pos.exclude_end?
    214           tail += 1
    215         end
    216         return self[head, tail-head]=value
    217       else
    218         pos += self.length if pos < 0
    219         if pos < 0 || pos > self.length
    220           raise IndexError, "index #{args[0]} out of string"
    221         end
    222         b = self[0, pos.to_i]
    223         a = self[pos + 1..-1]
    224         self.replace([b, value, a].join(''))
    225       end
    226       return value
    227     elsif anum == 3
    228       pos, len, value = args
    229       pos += self.length if pos < 0
    230       if pos < 0 || pos > self.length
    231         raise IndexError, "index #{args[0]} out of string"
    232       end
    233       if len < 0
    234         raise IndexError, "negative length #{len}"
    235       end
    236       b = self[0, pos.to_i]
    237       a = self[pos + len..-1]
    238       self.replace([b, value, a].join(''))
    239       return value
    240     else
    241       raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)"
    242     end
    243   end
    244 
     205  # those two methods requires Regexp that is optional in mruby
    245206  ##
    246207  # ISO 15.2.10.5.3
    247   def =~(re)
    248     raise TypeError, "type mismatch: String given" if re.respond_to? :to_str
    249     re =~ self
    250   end
     208  #def =~(re)
     209  # re =~ self
     210  #end
    251211
    252212  ##
    253213  # ISO 15.2.10.5.27
    254   def match(re, &block)
    255     if re.respond_to? :to_str
    256       if Object.const_defined?(:Regexp)
    257         r = Regexp.new(re)
    258         r.match(self, &block)
    259       else
    260         raise NotImplementedError, "String#match needs Regexp class"
    261       end
    262     else
    263       re.match(self, &block)
    264     end
    265   end
     214  #def match(re, &block)
     215  #  re.match(self, &block)
     216  #end
    266217end
    267 
    268 ##
    269 # String is comparable
    270 #
    271 # ISO 15.2.10.3
    272 module Comparable; end
    273 class String
    274   include Comparable
    275 end
  • EcnlProtoTool/trunk/mruby-2.1.1/mruby-source.gemspec

    r270 r439  
    1111  spec.summary       = %q{MRuby source code wrapper.}
    1212  spec.description   = %q{MRuby source code wrapper for use with Ruby libs.}
    13   spec.homepage      = "http://www.mruby.org/"
     13  spec.homepage      = "https://mruby.org"
    1414  spec.license       = "MIT"
    1515
  • EcnlProtoTool/trunk/mruby-2.1.1/src/array.c

    r331 r439  
    1010#include <mruby/string.h>
    1111#include <mruby/range.h>
     12#include <mruby/proc.h>
     13#include <mruby/opcode.h>
    1214#include "value_array.h"
    1315
     
    1517#define ARY_SHRINK_RATIO  5 /* must be larger than 2 */
    1618#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
    17 #define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1)
     19#define ARY_MAX_SIZE ((mrb_int)((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? ARY_C_MAX_SIZE : MRB_INT_MAX-1))
    1820
    1921static struct RArray*
     
    2931
    3032  a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
    31   a->ptr = (mrb_value *)mrb_malloc(mrb, blen);
    32   a->aux.capa = capa;
    33   a->len = 0;
     33  if (capa <= MRB_ARY_EMBED_LEN_MAX) {
     34    ARY_SET_EMBED_LEN(a, 0);
     35  }
     36  else {
     37    a->as.heap.ptr = (mrb_value *)mrb_malloc(mrb, blen);
     38    a->as.heap.aux.capa = capa;
     39    a->as.heap.len = 0;
     40  }
    3441
    3542  return a;
     
    7380}
    7481
     82static struct RArray*
     83ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals)
     84{
     85  struct RArray *a = ary_new_capa(mrb, size);
     86
     87  array_copy(ARY_PTR(a), vals, size);
     88  ARY_SET_LEN(a, size);
     89
     90  return a;
     91}
     92
    7593MRB_API mrb_value
    7694mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals)
    7795{
    78   struct RArray *a = ary_new_capa(mrb, size);
    79 
    80   array_copy(a->ptr, vals, size);
    81   a->len = size;
    82 
     96  struct RArray *a = ary_new_from_values(mrb, size, vals);
    8397  return mrb_obj_value(a);
    8498}
     
    90104
    91105  a = ary_new_capa(mrb, 2);
    92   a->ptr[0] = car;
    93   a->ptr[1] = cdr;
    94   a->len = 2;
     106  ARY_PTR(a)[0] = car;
     107  ARY_PTR(a)[1] = cdr;
     108  ARY_SET_LEN(a, 2);
    95109  return mrb_obj_value(a);
    96110}
     
    107121
    108122static void
     123ary_modify_check(mrb_state *mrb, struct RArray *a)
     124{
     125  mrb_check_frozen(mrb, a);
     126}
     127
     128static void
    109129ary_modify(mrb_state *mrb, struct RArray *a)
    110130{
    111   if (MRB_FROZEN_P(a)) {
    112     mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array");
    113   }
     131  ary_modify_check(mrb, a);
    114132
    115133  if (ARY_SHARED_P(a)) {
    116     mrb_shared_array *shared = a->aux.shared;
    117 
    118     if (shared->refcnt == 1 && a->ptr == shared->ptr) {
    119       a->ptr = shared->ptr;
    120       a->aux.capa = a->len;
     134    mrb_shared_array *shared = a->as.heap.aux.shared;
     135
     136    if (shared->refcnt == 1 && a->as.heap.ptr == shared->ptr) {
     137      a->as.heap.ptr = shared->ptr;
     138      a->as.heap.aux.capa = a->as.heap.len;
    121139      mrb_free(mrb, shared);
    122140    }
     
    125143      mrb_int len;
    126144
    127       p = a->ptr;
    128       len = a->len * sizeof(mrb_value);
     145      p = a->as.heap.ptr;
     146      len = a->as.heap.len * sizeof(mrb_value);
    129147      ptr = (mrb_value *)mrb_malloc(mrb, len);
    130148      if (p) {
    131         array_copy(ptr, p, a->len);
     149        array_copy(ptr, p, a->as.heap.len);
    132150      }
    133       a->ptr = ptr;
    134       a->aux.capa = a->len;
     151      a->as.heap.ptr = ptr;
     152      a->as.heap.aux.capa = a->as.heap.len;
    135153      mrb_ary_decref(mrb, shared);
    136154    }
     
    149167ary_make_shared(mrb_state *mrb, struct RArray *a)
    150168{
    151   if (!ARY_SHARED_P(a)) {
     169  if (!ARY_SHARED_P(a) && !ARY_EMBED_P(a)) {
    152170    mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array));
     171    mrb_value *ptr = a->as.heap.ptr;
     172    mrb_int len = a->as.heap.len;
    153173
    154174    shared->refcnt = 1;
    155     if (a->aux.capa > a->len) {
    156       a->ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*a->len+1);
     175    if (a->as.heap.aux.capa > len) {
     176      a->as.heap.ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1);
    157177    }
    158178    else {
    159       shared->ptr = a->ptr;
    160     }
    161     shared->len = a->len;
    162     a->aux.shared = shared;
     179      shared->ptr = ptr;
     180    }
     181    shared->len = len;
     182    a->as.heap.aux.shared = shared;
    163183    ARY_SET_SHARED_FLAG(a);
    164184  }
     
    168188ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len)
    169189{
    170   mrb_int capa = a->aux.capa;
    171 
    172   if (len > ARY_MAX_SIZE) {
     190  mrb_int capa = ARY_CAPA(a);
     191
     192  if (len > ARY_MAX_SIZE || len < 0) {
    173193  size_error:
    174194    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
    175195  }
    176196
    177   if (capa == 0) {
     197  if (capa < ARY_DEFAULT_LEN) {
    178198    capa = ARY_DEFAULT_LEN;
    179199  }
     
    190210  }
    191211
    192   if (capa > a->aux.capa) {
    193     mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa);
    194 
    195     a->aux.capa = capa;
    196     a->ptr = expanded_ptr;
     212  if (ARY_EMBED_P(a)) {
     213    mrb_value *ptr = ARY_EMBED_PTR(a);
     214    mrb_int len = ARY_EMBED_LEN(a);
     215    mrb_value *expanded_ptr = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*capa);
     216
     217    ARY_UNSET_EMBED_FLAG(a);
     218    array_copy(expanded_ptr, ptr, len);
     219    a->as.heap.len = len;
     220    a->as.heap.aux.capa = capa;
     221    a->as.heap.ptr = expanded_ptr;
     222  }
     223  else if (capa > a->as.heap.aux.capa) {
     224    mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa);
     225
     226    a->as.heap.aux.capa = capa;
     227    a->as.heap.ptr = expanded_ptr;
    197228  }
    198229}
     
    201232ary_shrink_capa(mrb_state *mrb, struct RArray *a)
    202233{
    203   mrb_int capa = a->aux.capa;
    204 
     234
     235  mrb_int capa;
     236
     237  if (ARY_EMBED_P(a)) return;
     238
     239  capa = a->as.heap.aux.capa;
    205240  if (capa < ARY_DEFAULT_LEN * 2) return;
    206   if (capa <= a->len * ARY_SHRINK_RATIO) return;
     241  if (capa <= a->as.heap.len * ARY_SHRINK_RATIO) return;
    207242
    208243  do {
     
    212247      break;
    213248    }
    214   } while (capa > a->len * ARY_SHRINK_RATIO);
    215 
    216   if (capa > a->len && capa < a->aux.capa) {
    217     a->aux.capa = capa;
    218     a->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa);
     249  } while (capa > a->as.heap.len * ARY_SHRINK_RATIO);
     250
     251  if (capa > a->as.heap.len && capa < a->as.heap.aux.capa) {
     252    a->as.heap.aux.capa = capa;
     253    a->as.heap.ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa);
    219254  }
    220255}
     
    229264  old_len = RARRAY_LEN(ary);
    230265  if (old_len != new_len) {
    231     a->len = new_len;
    232266    if (new_len < old_len) {
    233267      ary_shrink_capa(mrb, a);
     
    235269    else {
    236270      ary_expand_capa(mrb, a, new_len);
    237       ary_fill_with_nil(a->ptr + old_len, new_len - old_len);
    238     }
     271      ary_fill_with_nil(ARY_PTR(a) + old_len, new_len - old_len);
     272    }
     273    ARY_SET_LEN(a, new_len);
    239274  }
    240275
     
    250285  struct RArray *a;
    251286
    252   mrb_get_args(mrb, "*", &vals, &len);
     287  mrb_get_args(mrb, "*!", &vals, &len);
    253288  ary = mrb_ary_new_from_values(mrb, len, vals);
    254289  a = mrb_ary_ptr(ary);
     
    258293}
    259294
     295static void ary_replace(mrb_state*, struct RArray*, struct RArray*);
     296
    260297static void
    261298ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2)
     
    263300  mrb_int len;
    264301
    265   if (a2->len > ARY_MAX_SIZE - a->len) {
     302  if (ARY_LEN(a) == 0) {
     303    ary_replace(mrb, a, a2);
     304    return;
     305  }
     306  if (ARY_LEN(a2) > ARY_MAX_SIZE - ARY_LEN(a)) {
    266307    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
    267308  }
    268   len = a->len + a2->len;
     309  len = ARY_LEN(a) + ARY_LEN(a2);
    269310
    270311  ary_modify(mrb, a);
    271   if (a->aux.capa < len) {
     312  if (ARY_CAPA(a) < len) {
    272313    ary_expand_capa(mrb, a, len);
    273314  }
    274   array_copy(a->ptr+a->len, a2->ptr, a2->len);
     315  array_copy(ARY_PTR(a)+ARY_LEN(a), ARY_PTR(a2), ARY_LEN(a2));
    275316  mrb_write_barrier(mrb, (struct RBasic*)a);
    276   a->len = len;
     317  ARY_SET_LEN(a, len);
    277318}
    278319
     
    301342  struct RArray *a2;
    302343  mrb_value *ptr;
    303   mrb_int blen;
     344  mrb_int blen, len1;
    304345
    305346  mrb_get_args(mrb, "a", &ptr, &blen);
    306   if (ARY_MAX_SIZE - blen < a1->len) {
     347  if (ARY_MAX_SIZE - blen < ARY_LEN(a1)) {
    307348    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
    308349  }
    309   a2 = ary_new_capa(mrb, a1->len + blen);
    310   array_copy(a2->ptr, a1->ptr, a1->len);
    311   array_copy(a2->ptr + a1->len, ptr, blen);
    312   a2->len = a1->len + blen;
     350  len1 = ARY_LEN(a1);
     351  a2 = ary_new_capa(mrb, len1 + blen);
     352  array_copy(ARY_PTR(a2), ARY_PTR(a1), len1);
     353  array_copy(ARY_PTR(a2) + len1, ptr, blen);
     354  ARY_SET_LEN(a2, len1+blen);
    313355
    314356  return mrb_obj_value(a2);
    315357}
    316358
     359#define ARY_REPLACE_SHARED_MIN 20
     360
    317361static void
    318 ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len)
    319 {
    320   ary_modify(mrb, a);
    321   if (a->aux.capa < len)
     362ary_replace(mrb_state *mrb, struct RArray *a, struct RArray *b)
     363{
     364  mrb_int len = ARY_LEN(b);
     365
     366  ary_modify_check(mrb, a);
     367  if (a == b) return;
     368  if (ARY_SHARED_P(a)) {
     369    mrb_ary_decref(mrb, a->as.heap.aux.shared);
     370    a->as.heap.aux.capa = 0;
     371    a->as.heap.len = 0;
     372    a->as.heap.ptr = NULL;
     373    ARY_UNSET_SHARED_FLAG(a);
     374  }
     375  if (ARY_SHARED_P(b)) {
     376  shared_b:
     377    if (ARY_EMBED_P(a)) {
     378      ARY_UNSET_EMBED_FLAG(a);
     379    }
     380    else {
     381      mrb_free(mrb, a->as.heap.ptr);
     382    }
     383    a->as.heap.ptr = b->as.heap.ptr;
     384    a->as.heap.len = len;
     385    a->as.heap.aux.shared = b->as.heap.aux.shared;
     386    a->as.heap.aux.shared->refcnt++;
     387    ARY_SET_SHARED_FLAG(a);
     388    mrb_write_barrier(mrb, (struct RBasic*)a);
     389    return;
     390  }
     391  if (!mrb_frozen_p(b) && len > ARY_REPLACE_SHARED_MIN) {
     392    ary_make_shared(mrb, b);
     393    goto shared_b;
     394  }
     395  if (ARY_CAPA(a) < len)
    322396    ary_expand_capa(mrb, a, len);
    323   array_copy(a->ptr, argv, len);
     397  array_copy(ARY_PTR(a), ARY_PTR(b), len);
    324398  mrb_write_barrier(mrb, (struct RBasic*)a);
    325   a->len = len;
     399  ARY_SET_LEN(a, len);
    326400}
    327401
     
    333407
    334408  if (a1 != a2) {
    335     ary_replace(mrb, a1, a2->ptr, a2->len);
     409    ary_replace(mrb, a1, a2);
    336410  }
    337411}
     
    354428  struct RArray *a2;
    355429  mrb_value *ptr;
    356   mrb_int times;
     430  mrb_int times, len1;
    357431
    358432  mrb_get_args(mrb, "i", &times);
     
    361435  }
    362436  if (times == 0) return mrb_ary_new(mrb);
    363   if (ARY_MAX_SIZE / times < a1->len) {
     437  if (ARY_MAX_SIZE / times < ARY_LEN(a1)) {
    364438    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
    365439  }
    366   a2 = ary_new_capa(mrb, a1->len * times);
    367   ptr = a2->ptr;
     440  len1 = ARY_LEN(a1);
     441  a2 = ary_new_capa(mrb, len1 * times);
     442  ARY_SET_LEN(a2, len1 * times);
     443  ptr = ARY_PTR(a2);
    368444  while (times--) {
    369     array_copy(ptr, a1->ptr, a1->len);
    370     ptr += a1->len;
    371     a2->len += a1->len;
     445    array_copy(ptr, ARY_PTR(a1), len1);
     446    ptr += len1;
    372447  }
    373448
     
    379454{
    380455  struct RArray *a = mrb_ary_ptr(self);
    381 
    382   if (a->len > 1) {
     456  mrb_int len = ARY_LEN(a);
     457
     458  if (len > 1) {
    383459    mrb_value *p1, *p2;
    384460
    385461    ary_modify(mrb, a);
    386     p1 = a->ptr;
    387     p2 = a->ptr + a->len - 1;
     462    p1 = ARY_PTR(a);
     463    p2 = p1 + len - 1;
    388464
    389465    while (p1 < p2) {
     
    399475mrb_ary_reverse(mrb_state *mrb, mrb_value self)
    400476{
    401   struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, a->len);
    402 
    403   if (a->len > 0) {
     477  struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, ARY_LEN(a));
     478  mrb_int len = ARY_LEN(a);
     479
     480  if (len > 0) {
    404481    mrb_value *p1, *p2, *e;
    405482
    406     p1 = a->ptr;
    407     e  = p1 + a->len;
    408     p2 = b->ptr + a->len - 1;
     483    p1 = ARY_PTR(a);
     484    e  = p1 + len;
     485    p2 = ARY_PTR(b) + len - 1;
    409486    while (p1 < e) {
    410487      *p2-- = *p1++;
    411488    }
    412     b->len = a->len;
     489    ARY_SET_LEN(b, len);
    413490  }
    414491  return mrb_obj_value(b);
     
    419496{
    420497  struct RArray *a = mrb_ary_ptr(ary);
     498  mrb_int len = ARY_LEN(a);
    421499
    422500  ary_modify(mrb, a);
    423   if (a->len == a->aux.capa)
    424     ary_expand_capa(mrb, a, a->len + 1);
    425   a->ptr[a->len++] = elem;
     501  if (len == ARY_CAPA(a))
     502    ary_expand_capa(mrb, a, len + 1);
     503  ARY_PTR(a)[len] = elem;
     504  ARY_SET_LEN(a, len+1);
    426505  mrb_field_write_barrier_value(mrb, (struct RBasic*)a, elem);
    427506}
     
    431510{
    432511  mrb_value *argv;
    433   mrb_int len;
    434 
    435   mrb_get_args(mrb, "*", &argv, &len);
    436   while (len--) {
    437     mrb_ary_push(mrb, self, *argv++);
    438   }
     512  mrb_int len, len2, alen;
     513  struct RArray *a;
     514
     515  mrb_get_args(mrb, "*!", &argv, &alen);
     516  a = mrb_ary_ptr(self);
     517  ary_modify(mrb, a);
     518  len = ARY_LEN(a);
     519  len2 = len + alen;
     520  if (ARY_CAPA(a) < len2) {
     521    ary_expand_capa(mrb, a, len2);
     522  }
     523  array_copy(ARY_PTR(a)+len, argv, alen);
     524  ARY_SET_LEN(a, len2);
     525  mrb_write_barrier(mrb, (struct RBasic*)a);
    439526
    440527  return self;
     
    445532{
    446533  struct RArray *a = mrb_ary_ptr(ary);
    447 
    448   ary_modify(mrb, a);
    449   if (a->len == 0) return mrb_nil_value();
    450   return a->ptr[--a->len];
     534  mrb_int len = ARY_LEN(a);
     535
     536  ary_modify_check(mrb, a);
     537  if (len == 0) return mrb_nil_value();
     538  ARY_SET_LEN(a, len-1);
     539  return ARY_PTR(a)[len-1];
    451540}
    452541
     
    457546{
    458547  struct RArray *a = mrb_ary_ptr(self);
     548  mrb_int len = ARY_LEN(a);
    459549  mrb_value val;
    460550
    461   ary_modify(mrb, a);
    462   if (a->len == 0) return mrb_nil_value();
     551  ary_modify_check(mrb, a);
     552  if (len == 0) return mrb_nil_value();
    463553  if (ARY_SHARED_P(a)) {
    464554  L_SHIFT:
    465     val = a->ptr[0];
    466     a->ptr++;
    467     a->len--;
     555    val = a->as.heap.ptr[0];
     556    a->as.heap.ptr++;
     557    a->as.heap.len--;
    468558    return val;
    469559  }
    470   if (a->len > ARY_SHIFT_SHARED_MIN) {
     560  if (len > ARY_SHIFT_SHARED_MIN) {
    471561    ary_make_shared(mrb, a);
    472562    goto L_SHIFT;
    473563  }
    474564  else {
    475     mrb_value *ptr = a->ptr;
    476     mrb_int size = a->len;
     565    mrb_value *ptr = ARY_PTR(a);
     566    mrb_int size = len;
    477567
    478568    val = *ptr;
     
    481571      ++ptr;
    482572    }
    483     --a->len;
     573    ARY_SET_LEN(a, len-1);
    484574  }
    485575  return val;
     
    494584{
    495585  struct RArray *a = mrb_ary_ptr(self);
     586  mrb_int len = ARY_LEN(a);
    496587
    497588  if (ARY_SHARED_P(a)
    498       && a->aux.shared->refcnt == 1 /* shared only referenced from this array */
    499       && a->ptr - a->aux.shared->ptr >= 1) /* there's room for unshifted item */ {
    500     a->ptr--;
    501     a->ptr[0] = item;
     589      && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */
     590      && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= 1) /* there's room for unshifted item */ {
     591    a->as.heap.ptr--;
     592    a->as.heap.ptr[0] = item;
    502593  }
    503594  else {
     595    mrb_value *ptr;
     596
    504597    ary_modify(mrb, a);
    505     if (a->aux.capa < a->len + 1)
    506       ary_expand_capa(mrb, a, a->len + 1);
    507     value_move(a->ptr + 1, a->ptr, a->len);
    508     a->ptr[0] = item;
    509   }
    510   a->len++;
     598    if (ARY_CAPA(a) < len + 1)
     599      ary_expand_capa(mrb, a, len + 1);
     600    ptr = ARY_PTR(a);
     601    value_move(ptr + 1, ptr, len);
     602    ptr[0] = item;
     603  }
     604  ARY_SET_LEN(a, len+1);
    511605  mrb_field_write_barrier_value(mrb, (struct RBasic*)a, item);
    512606
     
    518612{
    519613  struct RArray *a = mrb_ary_ptr(self);
    520   mrb_value *vals;
    521   mrb_int len;
    522 
    523   mrb_get_args(mrb, "*", &vals, &len);
    524   if (len > ARY_MAX_SIZE - a->len) {
     614  mrb_value *vals, *ptr;
     615  mrb_int alen, len;
     616
     617  mrb_get_args(mrb, "*!", &vals, &alen);
     618  if (alen == 0) {
     619    ary_modify_check(mrb, a);
     620    return self;
     621  }
     622  len = ARY_LEN(a);
     623  if (alen > ARY_MAX_SIZE - len) {
    525624    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
    526625  }
    527626  if (ARY_SHARED_P(a)
    528       && a->aux.shared->refcnt == 1 /* shared only referenced from this array */
    529       && a->ptr - a->aux.shared->ptr >= len) /* there's room for unshifted item */ {
    530     a->ptr -= len;
     627      && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */
     628      && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= alen) /* there's room for unshifted item */ {
     629    ary_modify_check(mrb, a);
     630    a->as.heap.ptr -= alen;
     631    ptr = a->as.heap.ptr;
    531632  }
    532633  else {
     634    mrb_bool same = vals == ARY_PTR(a);
    533635    ary_modify(mrb, a);
    534     if (len == 0) return self;
    535     if (a->aux.capa < a->len + len)
    536       ary_expand_capa(mrb, a, a->len + len);
    537     value_move(a->ptr + len, a->ptr, a->len);
    538   }
    539   array_copy(a->ptr, vals, len);
    540   a->len += len;
    541   while (len--) {
    542     mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[len]);
     636    if (ARY_CAPA(a) < len + alen)
     637      ary_expand_capa(mrb, a, len + alen);
     638    ptr = ARY_PTR(a);
     639    value_move(ptr + alen, ptr, len);
     640    if (same) vals = ptr;
     641  }
     642  array_copy(ptr, vals, alen);
     643  ARY_SET_LEN(a, len+alen);
     644  while (alen--) {
     645    mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[alen]);
    543646  }
    544647
     
    550653{
    551654  struct RArray *a = mrb_ary_ptr(ary);
     655  mrb_int len = ARY_LEN(a);
    552656
    553657  /* range check */
    554   if (n < 0) n += a->len;
    555   if (n < 0 || a->len <= n) return mrb_nil_value();
    556 
    557   return a->ptr[n];
     658  if (n < 0) n += len;
     659  if (n < 0 || len <= n) return mrb_nil_value();
     660
     661  return ARY_PTR(a)[n];
    558662}
    559663
     
    562666{
    563667  struct RArray *a = mrb_ary_ptr(ary);
     668  mrb_int len = ARY_LEN(a);
    564669
    565670  ary_modify(mrb, a);
    566671  /* range check */
    567672  if (n < 0) {
    568     n += a->len;
     673    n += len;
    569674    if (n < 0) {
    570       mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of array", mrb_fixnum_value(n - a->len));
    571     }
    572   }
    573   if (a->len <= n) {
    574     if (a->aux.capa <= n)
     675      mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of array", n - len);
     676    }
     677  }
     678  if (len <= n) {
     679    if (ARY_CAPA(a) <= n)
    575680      ary_expand_capa(mrb, a, n + 1);
    576     ary_fill_with_nil(a->ptr + a->len, n + 1 - a->len);
    577     a->len = n + 1;
    578   }
    579 
    580   a->ptr[n] = val;
     681    ary_fill_with_nil(ARY_PTR(a) + len, n + 1 - len);
     682    ARY_SET_LEN(a, n+1);
     683  }
     684
     685  ARY_PTR(a)[n] = val;
    581686  mrb_field_write_barrier_value(mrb, (struct RBasic*)a, val);
    582687}
     
    585690ary_dup(mrb_state *mrb, struct RArray *a)
    586691{
    587   struct RArray *d = ary_new_capa(mrb, a->len);
    588 
    589   ary_replace(mrb, d, a->ptr, a->len);
    590   return d;
     692  return ary_new_from_values(mrb, ARY_LEN(a), ARY_PTR(a));
    591693}
    592694
     
    595697{
    596698  struct RArray *a = mrb_ary_ptr(ary);
     699  mrb_int alen = ARY_LEN(a);
    597700  const mrb_value *argv;
    598701  mrb_int argc;
     
    602705
    603706  /* len check */
    604   if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%S)", mrb_fixnum_value(len));
     707  if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%i)", len);
    605708
    606709  /* range check */
    607710  if (head < 0) {
    608     head += a->len;
     711    head += alen;
    609712    if (head < 0) {
    610713      mrb_raise(mrb, E_INDEX_ERROR, "index is out of array");
     
    612715  }
    613716  tail = head + len;
    614   if (a->len < len || a->len < tail) {
    615     len = a->len - head;
     717  if (alen < len || alen < tail) {
     718    len = alen - head;
    616719  }
    617720
     
    620723    argc = RARRAY_LEN(rpl);
    621724    argv = RARRAY_PTR(rpl);
    622     if (argv == a->ptr) {
     725    if (argv == ARY_PTR(a)) {
    623726      struct RArray *r;
    624727
     
    627730      }
    628731      r = ary_dup(mrb, a);
    629       argv = r->ptr;
     732      argv = ARY_PTR(r);
    630733    }
    631734  }
     
    634737    argv = &rpl;
    635738  }
    636   if (head >= a->len) {
     739  if (head >= alen) {
    637740    if (head > ARY_MAX_SIZE - argc) {
    638       mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head));
     741      mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", head);
    639742    }
    640743    len = head + argc;
    641     if (len > a->aux.capa) {
     744    if (len > ARY_CAPA(a)) {
    642745      ary_expand_capa(mrb, a, head + argc);
    643746    }
    644     ary_fill_with_nil(a->ptr + a->len, head - a->len);
     747    ary_fill_with_nil(ARY_PTR(a) + alen, head - alen);
    645748    if (argc > 0) {
    646       array_copy(a->ptr + head, argv, argc);
    647     }
    648     a->len = len;
     749      array_copy(ARY_PTR(a) + head, argv, argc);
     750    }
     751    ARY_SET_LEN(a, len);
    649752  }
    650753  else {
    651     mrb_int alen;
    652 
    653     if (a->len - len > ARY_MAX_SIZE - argc) {
    654       mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(a->len + argc - len));
    655     }
    656     alen = a->len + argc - len;
    657     if (alen > a->aux.capa) {
    658       ary_expand_capa(mrb, a, alen);
     754    mrb_int newlen;
     755
     756    if (alen - len > ARY_MAX_SIZE - argc) {
     757      mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", alen + argc - len);
     758    }
     759    newlen = alen + argc - len;
     760    if (newlen > ARY_CAPA(a)) {
     761      ary_expand_capa(mrb, a, newlen);
    659762    }
    660763
    661764    if (len != argc) {
     765      mrb_value *ptr = ARY_PTR(a);
    662766      tail = head + len;
    663       value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail);
    664       a->len = alen;
     767      value_move(ptr + head + argc, ptr + tail, alen - tail);
     768      ARY_SET_LEN(a, newlen);
    665769    }
    666770    if (argc > 0) {
    667       value_move(a->ptr + head, argv, argc);
     771      value_move(ARY_PTR(a) + head, argv, argc);
    668772    }
    669773  }
     
    687791  struct RArray *b;
    688792
     793  if (!ARY_SHARED_P(a) && len <= ARY_SHIFT_SHARED_MIN) {
     794    return mrb_ary_new_from_values(mrb, len, ARY_PTR(a)+beg);
     795  }
    689796  ary_make_shared(mrb, a);
    690797  b  = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
    691   b->ptr = a->ptr + beg;
    692   b->len = len;
    693   b->aux.shared = a->aux.shared;
    694   b->aux.shared->refcnt++;
     798  b->as.heap.ptr = a->as.heap.ptr + beg;
     799  b->as.heap.len = len;
     800  b->as.heap.aux.shared = a->as.heap.aux.shared;
     801  b->as.heap.aux.shared->refcnt++;
    695802  ARY_SET_SHARED_FLAG(b);
    696803
     
    704811    return mrb_fixnum(index);
    705812  }
     813#ifndef MRB_WITHOUT_FLOAT
    706814  else if (mrb_float_p(index)) {
    707815    return (mrb_int)mrb_float(index);
    708816  }
     817#endif
    709818  else {
    710819    mrb_int i, argc;
    711820    mrb_value *argv;
    712821
    713     mrb_get_args(mrb, "i*", &i, &argv, &argc);
     822    mrb_get_args(mrb, "i*!", &i, &argv, &argc);
    714823    return i;
    715824  }
     
    747856{
    748857  struct RArray *a = mrb_ary_ptr(self);
    749   mrb_int i, len;
     858  mrb_int i, len, alen;
    750859  mrb_value index;
    751860
     
    754863      /* a[n..m] */
    755864    case MRB_TT_RANGE:
    756       if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
     865      if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
    757866        return ary_subseq(mrb, a, i, len);
    758867      }
     
    768877
    769878  i = aget_index(mrb, index);
    770   if (i < 0) i += a->len;
    771   if (i < 0 || a->len < i) return mrb_nil_value();
     879  alen = ARY_LEN(a);
     880  if (i < 0) i += alen;
     881  if (i < 0 || alen < i) return mrb_nil_value();
    772882  if (len < 0) return mrb_nil_value();
    773   if (a->len == i) return mrb_ary_new(mrb);
    774   if (len > a->len - i) len = a->len - i;
     883  if (alen == i) return mrb_ary_new(mrb);
     884  if (len > alen - i) len = alen - i;
    775885
    776886  return ary_subseq(mrb, a, i, len);
     
    822932    /* a[n..m] = v */
    823933    switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) {
    824     case 0:                   /* not range */
     934    case MRB_RANGE_TYPE_MISMATCH:
    825935      mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
    826936      break;
    827     case 1:                   /* range */
     937    case MRB_RANGE_OK:
    828938      mrb_ary_splice(mrb, self, i, len, v2);
    829939      break;
    830     case 2:                   /* out of range */
    831       mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
     940    case MRB_RANGE_OUT:
     941      mrb_raisef(mrb, E_RANGE_ERROR, "%v out of range", v1);
    832942      break;
    833943    }
     
    847957  mrb_value val;
    848958  mrb_value *ptr;
    849   mrb_int len;
     959  mrb_int len, alen;
    850960
    851961  mrb_get_args(mrb, "i", &index);
    852   if (index < 0) index += a->len;
    853   if (index < 0 || a->len <= index) return mrb_nil_value();
     962  alen = ARY_LEN(a);
     963  if (index < 0) index += alen;
     964  if (index < 0 || alen <= index) return mrb_nil_value();
    854965
    855966  ary_modify(mrb, a);
    856   val = a->ptr[index];
    857 
    858   ptr = a->ptr + index;
    859   len = a->len - index;
     967  ptr = ARY_PTR(a);
     968  val = ptr[index];
     969
     970  ptr += index;
     971  len = alen - index;
    860972  while (--len) {
    861973    *ptr = *(ptr+1);
    862974    ++ptr;
    863975  }
    864   --a->len;
     976  ARY_SET_LEN(a, alen-1);
    865977
    866978  ary_shrink_capa(mrb, a);
     
    873985{
    874986  struct RArray *a = mrb_ary_ptr(self);
    875   mrb_int size;
    876 
    877   if (mrb_get_args(mrb, "|i", &size) == 0) {
    878     return (a->len > 0)? a->ptr[0]: mrb_nil_value();
    879   }
     987  mrb_int size, alen;
     988
     989  if (mrb_get_argc(mrb) == 0) {
     990    return (ARY_LEN(a) > 0)? ARY_PTR(a)[0]: mrb_nil_value();
     991  }
     992  mrb_get_args(mrb, "|i", &size);
    880993  if (size < 0) {
    881994    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
    882995  }
    883996
    884   if (size > a->len) size = a->len;
     997  alen = ARY_LEN(a);
     998  if (size > alen) size = alen;
    885999  if (ARY_SHARED_P(a)) {
    8861000    return ary_subseq(mrb, a, 0, size);
    8871001  }
    888   return mrb_ary_new_from_values(mrb, size, a->ptr);
     1002  return mrb_ary_new_from_values(mrb, size, ARY_PTR(a));
    8891003}
    8901004
     
    8931007{
    8941008  struct RArray *a = mrb_ary_ptr(self);
    895   mrb_int size;
    896 
    897   if (mrb_get_args(mrb, "|i", &size) == 0)
    898     return (a->len > 0)? a->ptr[a->len - 1]: mrb_nil_value();
     1009  mrb_int n, size, alen;
     1010
     1011  n = mrb_get_args(mrb, "|i", &size);
     1012  alen = ARY_LEN(a);
     1013  if (n == 0) {
     1014    return (alen > 0) ? ARY_PTR(a)[alen - 1]: mrb_nil_value();
     1015  }
    8991016
    9001017  if (size < 0) {
    9011018    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
    9021019  }
    903   if (size > a->len) size = a->len;
     1020  if (size > alen) size = alen;
    9041021  if (ARY_SHARED_P(a) || size > ARY_DEFAULT_LEN) {
    905     return ary_subseq(mrb, a, a->len - size, size);
    906   }
    907   return mrb_ary_new_from_values(mrb, size, a->ptr + a->len - size);
     1022    return ary_subseq(mrb, a, alen - size, size);
     1023  }
     1024  return mrb_ary_new_from_values(mrb, size, ARY_PTR(a) + alen - size);
    9081025}
    9091026
     
    9441061mrb_ary_splat(mrb_state *mrb, mrb_value v)
    9451062{
    946   mrb_value a, recv_class;
     1063  mrb_value a;
    9471064
    9481065  if (mrb_array_p(v)) {
     
    9551072
    9561073  a = mrb_funcall(mrb, v, "to_a", 0);
    957   if (mrb_array_p(a)) {
    958     return a;
    959   }
    960   else if (mrb_nil_p(a)) {
     1074  if (mrb_nil_p(a)) {
    9611075    return mrb_ary_new_from_values(mrb, 1, &v);
    9621076  }
    963   else {
    964     recv_class = mrb_obj_value(mrb_obj_class(mrb, v));
    965     mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)",
    966       recv_class,
    967       recv_class,
    968       mrb_obj_value(mrb_obj_class(mrb, a))
    969     );
    970     /* not reached */
    971     return mrb_undef_value();
    972   }
     1077  mrb_ensure_array_type(mrb, a);
     1078  return a;
    9731079}
    9741080
     
    9781084  struct RArray *a = mrb_ary_ptr(self);
    9791085
    980   return mrb_fixnum_value(a->len);
     1086  return mrb_fixnum_value(ARY_LEN(a));
    9811087}
    9821088
     
    9881094  ary_modify(mrb, a);
    9891095  if (ARY_SHARED_P(a)) {
    990     mrb_ary_decref(mrb, a->aux.shared);
     1096    mrb_ary_decref(mrb, a->as.heap.aux.shared);
    9911097    ARY_UNSET_SHARED_FLAG(a);
    9921098  }
    993   else {
    994     mrb_free(mrb, a->ptr);
    995   }
    996   a->len = 0;
    997   a->aux.capa = 0;
    998   a->ptr = 0;
     1099  else if (!ARY_EMBED_P(a)){
     1100    mrb_free(mrb, a->as.heap.ptr);
     1101  }
     1102  ARY_SET_EMBED_LEN(a, 0);
    9991103
    10001104  return self;
     
    10021106
    10031107static mrb_value
     1108mrb_ary_clear_m(mrb_state *mrb, mrb_value self)
     1109{
     1110  return mrb_ary_clear(mrb, self);
     1111}
     1112
     1113static mrb_value
    10041114mrb_ary_empty_p(mrb_state *mrb, mrb_value self)
    10051115{
    10061116  struct RArray *a = mrb_ary_ptr(self);
    10071117
    1008   return mrb_bool_value(a->len == 0);
    1009 }
    1010 
    1011 MRB_API mrb_value
    1012 mrb_check_array_type(mrb_state *mrb, mrb_value ary)
    1013 {
    1014   return mrb_check_convert_type(mrb, ary, MRB_TT_ARRAY, "Array", "to_ary");
     1118  return mrb_bool_value(ARY_LEN(a) == 0);
    10151119}
    10161120
     
    10211125    offset += RARRAY_LEN(ary);
    10221126  }
    1023   return ary_elt(ary, offset);
     1127  if (offset < 0 || RARRAY_LEN(ary) <= offset) {
     1128    return mrb_nil_value();
     1129  }
     1130  return RARRAY_PTR(ary)[offset];
    10241131}
    10251132
     
    10391146  mrb_ary_push(mrb, list, ary);
    10401147
    1041   result = mrb_str_buf_new(mrb, 64);
     1148  result = mrb_str_new_capa(mrb, 64);
    10421149
    10431150  for (i=0; i<RARRAY_LEN(ary); i++) {
     
    10651172          goto str_join;
    10661173        }
    1067         tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");
     1174        tmp = mrb_check_array_type(mrb, val);
    10681175        if (!mrb_nil_p(tmp)) {
    10691176          val = tmp;
     
    11391246}
    11401247
     1248/* internal method to convert multi-value to single value */
     1249static mrb_value
     1250mrb_ary_svalue(mrb_state *mrb, mrb_value ary)
     1251{
     1252  switch (RARRAY_LEN(ary)) {
     1253  case 0:
     1254    return mrb_nil_value();
     1255  case 1:
     1256    return RARRAY_PTR(ary)[0];
     1257  default:
     1258    return ary;
     1259  }
     1260}
     1261
     1262static const mrb_code each_iseq[] = {
     1263  OP_ENTER, 0x0, 0x00, 0x1,  /* OP_ENTER     0:0:0:0:0:0:1 */
     1264  OP_JMPIF, 0x1, 0x0, 19,    /* OP_JMPIF     R1  19 */
     1265  OP_LOADSELF, 0x3,          /* OP_LOADSELF  R3 */
     1266  OP_LOADSYM, 0x4, 0x0,      /* OP_LOADSYM   R4  :each*/
     1267  OP_SEND, 0x3, 0x1, 0x1,    /* OP_SEND      R3  :to_enum   1 */
     1268  OP_RETURN, 0x3,            /* OP_RETURN    R3 */
     1269  OP_LOADI_0, 0x2,           /* OP_LOADI_0   R2 */
     1270  OP_JMP, 0x0, 43,           /* OP_JMP       49 */
     1271  OP_MOVE, 0x3, 0x1,         /* OP_MOVE      R3  R1 */
     1272  OP_LOADSELF, 0x4,          /* OP_LOADSELF  R4 */
     1273  OP_MOVE, 0x5, 0x2,         /* OP_MOVE      R5  R2 */
     1274  OP_SEND, 0x4, 0x2, 0x1,    /* OP_SEND      R4  :[]        1 */
     1275  OP_SEND, 0x3, 0x3, 0x1,    /* OP_SEND      R3  :call      1 */
     1276  OP_ADDI, 0x2, 1,           /* OP_ADDI      R3  1 */
     1277  OP_MOVE, 0x3, 0x2,         /* OP_MOVE      R3  R2 */
     1278  OP_LOADSELF, 0x4,          /* OP_LOADSELF  R4 */
     1279  OP_SEND, 0x4, 0x4, 0x0,    /* OP_SEND      R4  :length    0 */
     1280  OP_LT, 0x3,                /* OP_LT        R3 */
     1281  OP_JMPIF, 0x3, 0x0, 24,    /* OP_JMPIF     R3  24 */
     1282  OP_RETURN, 0x0             /* OP_RETURN    R3 */
     1283};
     1284
     1285static void
     1286init_ary_each(mrb_state *mrb, struct RClass *ary)
     1287{
     1288  struct RProc *p;
     1289  mrb_method_t m;
     1290  mrb_irep *each_irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep));
     1291  static const mrb_irep mrb_irep_zero = { 0 };
     1292
     1293  *each_irep = mrb_irep_zero;
     1294  each_irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*5);
     1295  each_irep->syms[0] = mrb_intern_lit(mrb, "each");
     1296  each_irep->syms[1] = mrb_intern_lit(mrb, "to_enum");
     1297  each_irep->syms[2] = mrb_intern_lit(mrb, "[]");
     1298  each_irep->syms[3] = mrb_intern_lit(mrb, "call");
     1299  each_irep->syms[4] = mrb_intern_lit(mrb, "length");
     1300  each_irep->slen = 5;
     1301  each_irep->flags = MRB_ISEQ_NO_FREE;
     1302  each_irep->iseq = each_iseq;
     1303  each_irep->ilen = sizeof(each_iseq);
     1304  each_irep->nregs = 7;
     1305  each_irep->nlocals = 3;
     1306  p = mrb_proc_new(mrb, each_irep);
     1307  p->flags |= MRB_PROC_SCOPE | MRB_PROC_STRICT;
     1308  MRB_METHOD_FROM_PROC(m, p);
     1309  mrb_define_method_raw(mrb, ary, mrb_intern_lit(mrb, "each"), m);
     1310}
     1311
    11411312void
    11421313mrb_init_array(mrb_state *mrb)
     
    11441315  struct RClass *a;
    11451316
    1146   mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class);            /* 15.2.12 */
     1317  mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class);              /* 15.2.12 */
    11471318  MRB_SET_INSTANCE_TT(a, MRB_TT_ARRAY);
    11481319
    1149   mrb_define_class_method(mrb, a, "[]",        mrb_ary_s_create,     MRB_ARGS_ANY());  /* 15.2.12.4.1 */
    1150 
    1151   mrb_define_method(mrb, a, "+",               mrb_ary_plus,         MRB_ARGS_REQ(1)); /* 15.2.12.5.1  */
    1152   mrb_define_method(mrb, a, "*",               mrb_ary_times,        MRB_ARGS_REQ(1)); /* 15.2.12.5.2  */
    1153   mrb_define_method(mrb, a, "<<",              mrb_ary_push_m,       MRB_ARGS_REQ(1)); /* 15.2.12.5.3  */
    1154   mrb_define_method(mrb, a, "[]",              mrb_ary_aget,         MRB_ARGS_ANY());  /* 15.2.12.5.4  */
    1155   mrb_define_method(mrb, a, "[]=",             mrb_ary_aset,         MRB_ARGS_ANY());  /* 15.2.12.5.5  */
    1156   mrb_define_method(mrb, a, "clear",           mrb_ary_clear,        MRB_ARGS_NONE()); /* 15.2.12.5.6  */
    1157   mrb_define_method(mrb, a, "concat",          mrb_ary_concat_m,     MRB_ARGS_REQ(1)); /* 15.2.12.5.8  */
    1158   mrb_define_method(mrb, a, "delete_at",       mrb_ary_delete_at,    MRB_ARGS_REQ(1)); /* 15.2.12.5.9  */
    1159   mrb_define_method(mrb, a, "empty?",          mrb_ary_empty_p,      MRB_ARGS_NONE()); /* 15.2.12.5.12 */
    1160   mrb_define_method(mrb, a, "first",           mrb_ary_first,        MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */
    1161   mrb_define_method(mrb, a, "index",           mrb_ary_index_m,      MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */
    1162   mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m,    MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */
    1163   mrb_define_method(mrb, a, "join",            mrb_ary_join_m,       MRB_ARGS_ANY());  /* 15.2.12.5.17 */
    1164   mrb_define_method(mrb, a, "last",            mrb_ary_last,         MRB_ARGS_ANY());  /* 15.2.12.5.18 */
    1165   mrb_define_method(mrb, a, "length",          mrb_ary_size,         MRB_ARGS_NONE()); /* 15.2.12.5.19 */
    1166   mrb_define_method(mrb, a, "pop",             mrb_ary_pop,          MRB_ARGS_NONE()); /* 15.2.12.5.21 */
    1167   mrb_define_method(mrb, a, "push",            mrb_ary_push_m,       MRB_ARGS_ANY());  /* 15.2.12.5.22 */
    1168   mrb_define_method(mrb, a, "append",          mrb_ary_push_m,       MRB_ARGS_ANY());
    1169   mrb_define_method(mrb, a, "replace",         mrb_ary_replace_m,    MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */
    1170   mrb_define_method(mrb, a, "reverse",         mrb_ary_reverse,      MRB_ARGS_NONE()); /* 15.2.12.5.24 */
    1171   mrb_define_method(mrb, a, "reverse!",        mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */
    1172   mrb_define_method(mrb, a, "rindex",          mrb_ary_rindex_m,     MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */
    1173   mrb_define_method(mrb, a, "shift",           mrb_ary_shift,        MRB_ARGS_NONE()); /* 15.2.12.5.27 */
    1174   mrb_define_method(mrb, a, "size",            mrb_ary_size,         MRB_ARGS_NONE()); /* 15.2.12.5.28 */
    1175   mrb_define_method(mrb, a, "slice",           mrb_ary_aget,         MRB_ARGS_ANY());  /* 15.2.12.5.29 */
    1176   mrb_define_method(mrb, a, "unshift",         mrb_ary_unshift_m,    MRB_ARGS_ANY());  /* 15.2.12.5.30 */
    1177   mrb_define_method(mrb, a, "prepend",         mrb_ary_unshift_m,    MRB_ARGS_ANY());
     1320  mrb_define_class_method(mrb, a, "[]",        mrb_ary_s_create,     MRB_ARGS_ANY());    /* 15.2.12.4.1 */
     1321
     1322  mrb_define_method(mrb, a, "+",               mrb_ary_plus,         MRB_ARGS_REQ(1));   /* 15.2.12.5.1  */
     1323  mrb_define_method(mrb, a, "*",               mrb_ary_times,        MRB_ARGS_REQ(1));   /* 15.2.12.5.2  */
     1324  mrb_define_method(mrb, a, "<<",              mrb_ary_push_m,       MRB_ARGS_REQ(1));   /* 15.2.12.5.3  */
     1325  mrb_define_method(mrb, a, "[]",              mrb_ary_aget,         MRB_ARGS_ARG(1,1)); /* 15.2.12.5.4  */
     1326  mrb_define_method(mrb, a, "[]=",             mrb_ary_aset,         MRB_ARGS_ARG(2,1)); /* 15.2.12.5.5  */
     1327  mrb_define_method(mrb, a, "clear",           mrb_ary_clear_m,      MRB_ARGS_NONE());   /* 15.2.12.5.6  */
     1328  mrb_define_method(mrb, a, "concat",          mrb_ary_concat_m,     MRB_ARGS_REQ(1));   /* 15.2.12.5.8  */
     1329  mrb_define_method(mrb, a, "delete_at",       mrb_ary_delete_at,    MRB_ARGS_REQ(1));   /* 15.2.12.5.9  */
     1330  mrb_define_method(mrb, a, "empty?",          mrb_ary_empty_p,      MRB_ARGS_NONE());   /* 15.2.12.5.12 */
     1331  mrb_define_method(mrb, a, "first",           mrb_ary_first,        MRB_ARGS_OPT(1));   /* 15.2.12.5.13 */
     1332  mrb_define_method(mrb, a, "index",           mrb_ary_index_m,      MRB_ARGS_REQ(1));   /* 15.2.12.5.14 */
     1333  mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m,    MRB_ARGS_REQ(1));   /* 15.2.12.5.16 */
     1334  mrb_define_method(mrb, a, "join",            mrb_ary_join_m,       MRB_ARGS_OPT(1));   /* 15.2.12.5.17 */
     1335  mrb_define_method(mrb, a, "last",            mrb_ary_last,         MRB_ARGS_OPT(1));   /* 15.2.12.5.18 */
     1336  mrb_define_method(mrb, a, "length",          mrb_ary_size,         MRB_ARGS_NONE());   /* 15.2.12.5.19 */
     1337  mrb_define_method(mrb, a, "pop",             mrb_ary_pop,          MRB_ARGS_NONE());   /* 15.2.12.5.21 */
     1338  mrb_define_method(mrb, a, "push",            mrb_ary_push_m,       MRB_ARGS_ANY());    /* 15.2.12.5.22 */
     1339  mrb_define_method(mrb, a, "replace",         mrb_ary_replace_m,    MRB_ARGS_REQ(1));   /* 15.2.12.5.23 */
     1340  mrb_define_method(mrb, a, "reverse",         mrb_ary_reverse,      MRB_ARGS_NONE());   /* 15.2.12.5.24 */
     1341  mrb_define_method(mrb, a, "reverse!",        mrb_ary_reverse_bang, MRB_ARGS_NONE());   /* 15.2.12.5.25 */
     1342  mrb_define_method(mrb, a, "rindex",          mrb_ary_rindex_m,     MRB_ARGS_REQ(1));   /* 15.2.12.5.26 */
     1343  mrb_define_method(mrb, a, "shift",           mrb_ary_shift,        MRB_ARGS_NONE());   /* 15.2.12.5.27 */
     1344  mrb_define_method(mrb, a, "size",            mrb_ary_size,         MRB_ARGS_NONE());   /* 15.2.12.5.28 */
     1345  mrb_define_method(mrb, a, "slice",           mrb_ary_aget,         MRB_ARGS_ARG(1,1)); /* 15.2.12.5.29 */
     1346  mrb_define_method(mrb, a, "unshift",         mrb_ary_unshift_m,    MRB_ARGS_ANY());    /* 15.2.12.5.30 */
    11781347
    11791348  mrb_define_method(mrb, a, "__ary_eq",        mrb_ary_eq,           MRB_ARGS_REQ(1));
    11801349  mrb_define_method(mrb, a, "__ary_cmp",       mrb_ary_cmp,          MRB_ARGS_REQ(1));
    1181   mrb_define_method(mrb, a, "__ary_index",     mrb_ary_index_m,      MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */
    1182 }
     1350  mrb_define_method(mrb, a, "__ary_index",     mrb_ary_index_m,      MRB_ARGS_REQ(1));   /* kept for mruby-array-ext */
     1351  mrb_define_method(mrb, a, "__svalue",        mrb_ary_svalue,       MRB_ARGS_NONE());
     1352
     1353  init_ary_each(mrb, a);
     1354}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/backtrace.c

    r331 r439  
    1717
    1818struct backtrace_location {
    19   int lineno;
     19  int32_t lineno;
     20  mrb_sym method_id;
    2021  const char *filename;
    21   mrb_sym method_id;
    2222};
    2323
    24 typedef void (*each_backtrace_func)(mrb_state*, int i, struct backtrace_location*, void*);
     24typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*, void*);
    2525
    2626static const mrb_data_type bt_type = { "Backtrace", mrb_free };
    2727
    28 static void
    29 each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func func, void *data)
    30 {
    31   int i, j;
     28mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
     29mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace);
     30
     31static void
     32each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data)
     33{
     34  ptrdiff_t i;
    3235
    3336  if (ciidx >= mrb->c->ciend - mrb->c->cibase)
    3437    ciidx = 10; /* ciidx is broken... */
    3538
    36   for (i=ciidx, j=0; i >= 0; i--,j++) {
     39  for (i=ciidx; i >= 0; i--) {
    3740    struct backtrace_location loc;
    3841    mrb_callinfo *ci;
    3942    mrb_irep *irep;
    40     mrb_code *pc;
     43    const mrb_code *pc;
    4144
    4245    ci = &mrb->c->cibase[i];
     
    5255    }
    5356    else if (i+1 <= ciidx) {
    54       pc = mrb->c->cibase[i+1].pc - 1;
     57      if (!mrb->c->cibase[i + 1].pc) continue;
     58      pc = &mrb->c->cibase[i+1].pc[-1];
    5559    }
    5660    else {
    5761      pc = pc0;
    5862    }
    59     loc.filename = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));
    60     loc.lineno = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));
    61 
     63
     64    loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq);
    6265    if (loc.lineno == -1) continue;
    6366
     67    loc.filename = mrb_debug_get_filename(mrb, irep, pc - irep->iseq);
    6468    if (!loc.filename) {
    6569      loc.filename = "(unknown)";
     
    6771
    6872    loc.method_id = ci->mid;
    69     func(mrb, j, &loc, data);
     73    func(mrb, &loc, data);
    7074  }
    7175}
     
    7478
    7579static void
    76 print_backtrace(mrb_state *mrb, mrb_value backtrace)
    77 {
    78   int i, n;
     80print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace)
     81{
     82  mrb_int i;
     83  mrb_int n = RARRAY_LEN(backtrace);
     84  mrb_value *loc, mesg;
    7985  FILE *stream = stderr;
    8086
    81   if (!mrb_array_p(backtrace)) return;
    82   fprintf(stream, "trace:\n");
    83 
    84   n = RARRAY_LEN(backtrace);
    85   for (i=0; n--; i++) {
    86     mrb_value entry = RARRAY_PTR(backtrace)[n];
    87 
    88     if (mrb_string_p(entry)) {
    89       fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry));
    90     }
    91   }
    92 }
    93 
    94 static void
    95 print_packed_backtrace(mrb_state *mrb, mrb_value packed)
    96 {
    97   FILE *stream = stderr;
    98   struct backtrace_location *bt;
    99   int n, i;
    100 
    101   bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type);
    102   if (bt == NULL) {
    103     mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
    104   }
    105   n = (mrb_int)RDATA(packed)->flags;
    106 
    107   fprintf(stream, "trace:\n");
    108   for (i = 0; n--; i++) {
    109     int ai = mrb_gc_arena_save(mrb);
    110     struct backtrace_location *entry = &bt[n];
    111     if (entry->filename == NULL) continue;
    112     fprintf(stream, "\t[%d] %s:%d", (int)i, entry->filename, entry->lineno);
    113     if (entry->method_id != 0) {
    114       const char *method_name;
    115 
    116       method_name = mrb_sym2name(mrb, entry->method_id);
    117       fprintf(stream, ":in %s", method_name);
    118       mrb_gc_arena_restore(mrb, ai);
    119     }
    120     fprintf(stream, "\n");
    121   }
     87  if (n != 0) {
     88    fprintf(stream, "trace (most recent call last):\n");
     89    for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) {
     90      if (mrb_string_p(*loc)) {
     91        fprintf(stream, "\t[%d] %.*s\n",
     92                (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
     93      }
     94    }
     95    if (mrb_string_p(*loc)) {
     96      fprintf(stream, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
     97    }
     98  }
     99  mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc));
     100  fprintf(stream, "%.*s\n", (int)RSTRING_LEN(mesg), RSTRING_PTR(mesg));
    122101}
    123102
     
    138117  backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
    139118  if (mrb_nil_p(backtrace)) return;
    140   if (mrb_array_p(backtrace)) {
    141     print_backtrace(mrb, backtrace);
    142   }
    143   else {
    144     print_packed_backtrace(mrb, backtrace);
    145   }
     119  if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace);
     120  print_backtrace(mrb, mrb->exc, backtrace);
    146121}
    147122#else
     
    155130
    156131static void
     132count_backtrace_i(mrb_state *mrb,
     133                 const struct backtrace_location *loc,
     134                 void *data)
     135{
     136  int *lenp = (int*)data;
     137
     138  (*lenp)++;
     139}
     140
     141static void
    157142pack_backtrace_i(mrb_state *mrb,
    158                  int i,
    159                  struct backtrace_location *loc,
     143                 const struct backtrace_location *loc,
    160144                 void *data)
    161145{
    162   struct backtrace_location *entry = (struct backtrace_location*)data;
    163 
    164   entry[i] = *loc;
     146  struct backtrace_location **pptr = (struct backtrace_location**)data;
     147  struct backtrace_location *ptr = *pptr;
     148
     149  *ptr = *loc;
     150  *pptr = ptr+1;
    165151}
    166152
     
    170156  struct RData *backtrace;
    171157  ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase;
    172   mrb_int len = (ciidx+1)*sizeof(struct backtrace_location);
     158  int len = 0;
     159  int size;
    173160  void *ptr;
    174161
    175   ptr = mrb_malloc(mrb, len);
    176   memset(ptr, 0, len);
     162  each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len);
     163  size = len * sizeof(struct backtrace_location);
     164  ptr = mrb_malloc(mrb, size);
    177165  backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
    178   backtrace->flags = (unsigned int)ciidx+1;
    179   each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, ptr);
     166  backtrace->flags = (uint32_t)len;
     167  each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr);
    180168  return mrb_obj_value(backtrace);
    181169}
     
    184172mrb_keep_backtrace(mrb_state *mrb, mrb_value exc)
    185173{
     174  mrb_sym sym = mrb_intern_lit(mrb, "backtrace");
    186175  mrb_value backtrace;
    187   int ai = mrb_gc_arena_save(mrb);
    188 
     176  int ai;
     177
     178  if (mrb_iv_defined(mrb, exc, sym)) return;
     179  ai = mrb_gc_arena_save(mrb);
    189180  backtrace = packed_backtrace(mrb);
    190   mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);
     181  mrb_iv_set(mrb, exc, sym, backtrace);
    191182  mrb_gc_arena_restore(mrb, ai);
    192183}
     
    195186mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
    196187{
    197   struct backtrace_location *bt;
     188  const struct backtrace_location *bt;
    198189  mrb_int n, i;
    199 
    200   if (mrb_nil_p(backtrace)) return mrb_ary_new_capa(mrb, 0);
     190  int ai;
     191
     192  if (mrb_nil_p(backtrace)) {
     193  empty_backtrace:
     194    return mrb_ary_new_capa(mrb, 0);
     195  }
    201196  if (mrb_array_p(backtrace)) return backtrace;
    202197  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type);
    203   if (bt == NULL) {
    204     mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
    205   }
     198  if (bt == NULL) goto empty_backtrace;
    206199  n = (mrb_int)RDATA(backtrace)->flags;
    207200  backtrace = mrb_ary_new_capa(mrb, n);
     201  ai = mrb_gc_arena_save(mrb);
    208202  for (i = 0; i < n; i++) {
    209     int ai = mrb_gc_arena_save(mrb);
    210     struct backtrace_location *entry = &bt[i];
     203    const struct backtrace_location *entry = &bt[i];
    211204    mrb_value btline;
    212205
    213     if (entry->filename == NULL) continue;
    214     btline = mrb_format(mrb, "%S:%S",
    215                               mrb_str_new_cstr(mrb, entry->filename),
    216                               mrb_fixnum_value(entry->lineno));
     206    btline = mrb_format(mrb, "%s:%d", entry->filename, (int)entry->lineno);
    217207    if (entry->method_id != 0) {
    218208      mrb_str_cat_lit(mrb, btline, ":in ");
    219       mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id));
     209      mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id));
    220210    }
    221211    mrb_ary_push(mrb, backtrace, btline);
  • EcnlProtoTool/trunk/mruby-2.1.1/src/class.c

    r331 r439  
    88#include <mruby.h>
    99#include <mruby/array.h>
     10#include <mruby/hash.h>
    1011#include <mruby/class.h>
    1112#include <mruby/numeric.h>
     
    1617#include <mruby/data.h>
    1718#include <mruby/istruct.h>
    18 
    19 KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal)
     19#include <mruby/opcode.h>
     20
     21KHASH_DEFINE(mt, mrb_sym, mrb_method_t, TRUE, kh_int_hash_func, kh_int_hash_equal)
    2022
    2123void
     
    2830  for (k = kh_begin(h); k != kh_end(h); k++) {
    2931    if (kh_exist(h, k)) {
    30       struct RProc *m = kh_value(h, k);
    31       if (m) {
    32         mrb_gc_mark(mrb, (struct RBasic*)m);
     32      mrb_method_t m = kh_value(h, k);
     33
     34      if (MRB_METHOD_PROC_P(m)) {
     35        struct RProc *p = MRB_METHOD_PROC(m);
     36        mrb_gc_mark(mrb, (struct RBasic*)p);
    3337      }
    3438    }
     
    5155}
    5256
    53 static void
    54 name_class(mrb_state *mrb, struct RClass *c, mrb_sym name)
    55 {
    56   mrb_obj_iv_set(mrb, (struct RObject*)c,
    57                  mrb_intern_lit(mrb, "__classid__"), mrb_symbol_value(name));
     57void
     58mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
     59{
     60  mrb_value name;
     61  mrb_sym nsym = mrb_intern_lit(mrb, "__classname__");
     62
     63  if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return;
     64  if (outer == NULL || outer == mrb->object_class) {
     65    name = mrb_symbol_value(id);
     66  }
     67  else {
     68    name = mrb_class_path(mrb, outer);
     69    if (mrb_nil_p(name)) {      /* unnamed outer class */
     70      if (outer != mrb->object_class && outer != c) {
     71        mrb_obj_iv_set_force(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
     72                             mrb_obj_value(outer));
     73      }
     74      return;
     75    }
     76    else {
     77      mrb_int len;
     78      const char *n = mrb_sym_name_len(mrb, id, &len);
     79
     80      mrb_str_cat_lit(mrb, name, "::");
     81      mrb_str_cat(mrb, name, n, len);
     82    }
     83  }
     84  mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name);
     85}
     86
     87mrb_bool
     88mrb_const_name_p(mrb_state *mrb, const char *name, mrb_int len)
     89{
     90  return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
    5891}
    5992
     
    6194setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
    6295{
    63   name_class(mrb, c, id);
     96  mrb_class_name_class(mrb, outer, c, id);
    6497  mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c));
    65   if (outer != mrb->object_class) {
    66     mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
    67                    mrb_obj_value(outer));
    68   }
    6998}
    7099
     
    78107  if (o->c->tt == MRB_TT_SCLASS) return;
    79108  sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class);
     109  sc->flags |= MRB_FL_CLASS_IS_INHERITED;
    80110  sc->mt = kh_init(mt, mrb);
    81111  sc->iv = 0;
     
    104134  mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o);
    105135  mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o));
    106 }
    107 
    108 static struct RClass *
     136  sc->flags |= o->flags & MRB_FL_OBJ_IS_FROZEN;
     137}
     138
     139static mrb_value
     140class_name_str(mrb_state *mrb, struct RClass* c)
     141{
     142  mrb_value path = mrb_class_path(mrb, c);
     143  if (mrb_nil_p(path)) {
     144    path = c->tt == MRB_TT_MODULE ? mrb_str_new_lit(mrb, "#<Module:") :
     145                                    mrb_str_new_lit(mrb, "#<Class:");
     146    mrb_str_cat_str(mrb, path, mrb_ptr_to_str(mrb, c));
     147    mrb_str_cat_lit(mrb, path, ">");
     148  }
     149  return path;
     150}
     151
     152static struct RClass*
    109153class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
    110154{
     
    115159}
    116160
    117 static struct RClass *
     161static struct RClass*
    118162module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
    119163{
     
    137181}
    138182
    139 MRB_API struct RClass*
    140 mrb_class_outer_module(mrb_state *mrb, struct RClass *c)
    141 {
    142   mrb_value outer;
    143   struct RClass *cls;
    144 
    145   outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
    146   if (mrb_nil_p(outer)) return NULL;
    147   cls = mrb_class_ptr(outer);
    148   if (cls->tt == MRB_TT_SCLASS)
    149   {
    150     mrb_value klass;
    151     klass = mrb_obj_iv_get(mrb, (struct RObject *)cls,
    152                            mrb_intern_lit(mrb, "__attached__"));
    153     if (class_ptr_p(klass)) {
    154       cls = mrb_class_ptr(klass);
    155     }
    156   }
    157   return cls;
    158 }
    159 
    160183static void
    161184check_if_class_or_module(mrb_state *mrb, mrb_value obj)
    162185{
    163186  if (!class_ptr_p(obj)) {
    164     mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj));
     187    mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class/module", obj);
    165188  }
    166189}
     
    192215}
    193216
    194 MRB_API struct RClass*
     217struct RClass*
    195218mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id)
    196219{
     
    199222    mrb_value old = mrb_const_get(mrb, outer, id);
    200223
    201     if (mrb_type(old) != MRB_TT_MODULE) {
    202       mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old));
     224    if (!mrb_module_p(old)) {
     225      mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old);
    203226    }
    204227    return mrb_class_ptr(old);
     
    233256    MRB_CLASS_ORIGIN(c);
    234257    if (super && mrb_class_real(c->super) != super) {
    235       mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)",
    236                  mrb_sym2str(mrb, name),
    237                  mrb_obj_value(c->super), mrb_obj_value(super));
     258      mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %n (%C not %C)",
     259                 name, c->super, super);
    238260    }
    239261    return c;
     
    250272{
    251273  if (!super) {
    252     mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name));
     274    mrb_warn(mrb, "no super class for '%n', Object assumed", name);
    253275  }
    254276  return define_class(mrb, name, super, mrb->object_class);
     
    261283}
    262284
    263 static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value cv);
     285static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value);
     286#ifdef MRB_METHOD_CACHE
     287static void mc_clear_all(mrb_state *mrb);
     288static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym);
     289#else
     290#define mc_clear_all(mrb)
     291#define mc_clear_by_id(mrb,c,s)
     292#endif
    264293
    265294static void
     
    271300  if (!super)
    272301    super = mrb->object_class;
     302  super->flags |= MRB_FL_CLASS_IS_INHERITED;
    273303  s = mrb_obj_value(super);
     304  mrb_mc_clear_by_class(mrb, klass);
    274305  mid = mrb_intern_lit(mrb, "inherited");
    275306  if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) {
    276307    mrb_value c = mrb_obj_value(klass);
    277     mrb_funcall_argv(mrb, mrb_obj_value(super), mid, 1, &c);
    278   }
    279 }
    280 
    281 MRB_API struct RClass*
     308    mrb_funcall_argv(mrb, s, mid, 1, &c);
     309  }
     310}
     311
     312struct RClass*
    282313mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
    283314{
     
    286317
    287318  if (!mrb_nil_p(super)) {
    288     if (mrb_type(super) != MRB_TT_CLASS) {
    289       mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)",
    290                  mrb_inspect(mrb, super));
     319    if (!mrb_class_p(super)) {
     320      mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super);
    291321    }
    292322    s = mrb_class_ptr(super);
     
    299329    mrb_value old = mrb_const_get(mrb, outer, id);
    300330
    301     if (mrb_type(old) != MRB_TT_CLASS) {
    302       mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old));
     331    if (!mrb_class_p(old)) {
     332      mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old);
    303333    }
    304334    c = mrb_class_ptr(old);
     
    306336      /* check super class */
    307337      if (mrb_class_real(c->super) != s) {
    308         mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old);
     338        mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %v", old);
    309339      }
    310340    }
     
    337367}
    338368
    339 MRB_API struct RClass *
     369MRB_API struct RClass*
    340370mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
    341371{
     
    343373}
    344374
    345 MRB_API struct RClass *
     375MRB_API struct RClass*
    346376mrb_class_get(mrb_state *mrb, const char *name)
    347377{
     
    349379}
    350380
    351 MRB_API struct RClass *
     381MRB_API struct RClass*
    352382mrb_exc_get(mrb_state *mrb, const char *name)
    353383{
     
    356386                              mrb_intern_cstr(mrb, name));
    357387
    358   if (mrb_type(c) != MRB_TT_CLASS) {
     388  if (!mrb_class_p(c)) {
    359389    mrb_raise(mrb, mrb->eException_class, "exception corrupted");
    360390  }
     
    369399}
    370400
    371 MRB_API struct RClass *
     401MRB_API struct RClass*
    372402mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
    373403{
     
    375405}
    376406
    377 MRB_API struct RClass *
     407MRB_API struct RClass*
    378408mrb_module_get(mrb_state *mrb, const char *name)
    379409{
     
    384414 * Defines a class under the namespace of \a outer.
    385415 * \param outer  a class which contains the new class.
    386  * \param id     name of the new class
     416 * \param name     name of the new class
    387417 * \param super  a class from which the new class will derive.
    388418 *               NULL means \c Object class.
     
    397427 *       \a super, the function just returns the defined class.
    398428 */
    399 MRB_API struct RClass *
     429MRB_API struct RClass*
    400430mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
    401431{
     
    405435#if 0
    406436  if (!super) {
    407     mrb_warn(mrb, "no super class for '%S::%S', Object assumed",
    408              mrb_obj_value(outer), mrb_sym2str(mrb, id));
     437    mrb_warn(mrb, "no super class for '%C::%n', Object assumed", outer, id);
    409438  }
    410439#endif
     
    415444
    416445MRB_API void
    417 mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p)
     446mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_t m)
    418447{
    419448  khash_t(mt) *h;
     
    422451  h = c->mt;
    423452
    424   if (MRB_FROZEN_P(c)) {
    425     if (c->tt == MRB_TT_MODULE)
    426       mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen module");
    427     else
    428       mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen class");
    429   }
     453  mrb_check_frozen(mrb, c);
    430454  if (!h) h = c->mt = kh_init(mt, mrb);
    431455  k = kh_put(mt, mrb, h, mid);
    432   kh_value(h, k) = p;
    433   if (p) {
     456  kh_value(h, k) = m;
     457  if (MRB_METHOD_PROC_P(m) && !MRB_METHOD_UNDEF_P(m)) {
     458    struct RProc *p = MRB_METHOD_PROC(m);
     459
     460    p->flags |= MRB_PROC_SCOPE;
    434461    p->c = NULL;
    435     mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p);
    436   }
     462    mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p);
     463    if (!MRB_PROC_ENV_P(p)) {
     464      MRB_PROC_SET_TARGET_CLASS(p, c);
     465    }
     466  }
     467  mc_clear_by_id(mrb, c, mid);
    437468}
    438469
     
    440471mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
    441472{
    442   struct RProc *p;
     473  mrb_method_t m;
    443474  int ai = mrb_gc_arena_save(mrb);
    444475
    445   p = mrb_proc_new_cfunc(mrb, func);
    446   p->target_class = c;
    447   mrb_define_method_raw(mrb, c, mid, p);
     476  MRB_METHOD_FROM_FUNC(m, func);
     477  if (aspec == MRB_ARGS_NONE()) {
     478    MRB_METHOD_NOARG_SET(m);
     479  }
     480  mrb_define_method_raw(mrb, c, mid, m);
    448481  mrb_gc_arena_restore(mrb, ai);
    449482}
     
    459492mrb_notimplement(mrb_state *mrb)
    460493{
    461   const char *str;
    462   mrb_int len;
    463494  mrb_callinfo *ci = mrb->c->ci;
    464495
    465496  if (ci->mid) {
    466     str = mrb_sym2name_len(mrb, ci->mid, &len);
    467     mrb_raisef(mrb, E_NOTIMP_ERROR,
    468       "%S() function is unimplemented on this machine",
    469       mrb_str_new_static(mrb, str, (size_t)len));
     497    mrb_raisef(mrb, E_NOTIMP_ERROR, "%n() function is unimplemented on this machine", ci->mid);
    470498  }
    471499}
     
    481509
    482510static mrb_value
    483 check_type(mrb_state *mrb, mrb_value val, enum mrb_vtype t, const char *c, const char *m)
    484 {
    485   mrb_value tmp;
    486 
    487   tmp = mrb_check_convert_type(mrb, val, t, c, m);
    488   if (mrb_nil_p(tmp)) {
    489     mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_cstr(mrb, c));
    490   }
    491   return tmp;
    492 }
    493 
    494 static mrb_value
    495 to_str(mrb_state *mrb, mrb_value val)
    496 {
    497   return check_type(mrb, val, MRB_TT_STRING, "String", "to_str");
    498 }
    499 
    500 static mrb_value
    501511to_ary(mrb_state *mrb, mrb_value val)
    502512{
    503   return check_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");
     513  mrb_check_type(mrb, val, MRB_TT_ARRAY);
     514  return val;
    504515}
    505516
     
    507518to_hash(mrb_state *mrb, mrb_value val)
    508519{
    509   return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash");
    510 }
    511 
    512 static mrb_sym
    513 to_sym(mrb_state *mrb, mrb_value ss)
    514 {
    515   if (mrb_type(ss) == MRB_TT_SYMBOL) {
    516     return mrb_symbol(ss);
    517   }
    518   else if (mrb_string_p(ss)) {
    519     return mrb_intern_str(mrb, to_str(mrb, ss));
    520   }
    521   else {
    522     mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0);
    523     mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj);
    524     /* not reached */
    525     return 0;
    526   }
    527 }
     520  mrb_check_type(mrb, val, MRB_TT_HASH);
     521  return val;
     522}
     523
     524#define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss)
     525
     526MRB_API mrb_int
     527mrb_get_argc(mrb_state *mrb)
     528{
     529  mrb_int argc = mrb->c->ci->argc;
     530
     531  if (argc < 0) {
     532    struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
     533
     534    argc = ARY_LEN(a);
     535  }
     536  return argc;
     537}
     538
     539MRB_API mrb_value*
     540mrb_get_argv(mrb_state *mrb)
     541{
     542  mrb_int argc = mrb->c->ci->argc;
     543  mrb_value *array_argv = mrb->c->stack + 1;
     544  if (argc < 0) {
     545    struct RArray *a = mrb_ary_ptr(*array_argv);
     546
     547    array_argv = ARY_PTR(a);
     548  }
     549  return array_argv;
     550}
     551
     552void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
    528553
    529554/*
     
    539564    ----------------------------------------------------------------------------------------------
    540565    o:      Object         [mrb_value]
    541     C:      class/module   [mrb_value]
     566    C:      Class/Module   [mrb_value]
    542567    S:      String         [mrb_value]            when ! follows, the value may be nil
    543568    A:      Array          [mrb_value]            when ! follows, the value may be nil
     
    546571    z:      String         [char*]                NUL terminated string; z! gives NULL for nil
    547572    a:      Array          [mrb_value*,mrb_int]   Receive two arguments; a! gives (NULL,0) for nil
    548     f:      Float          [mrb_float]
    549     i:      Integer        [mrb_int]
    550     b:      Boolean        [mrb_bool]
    551     n:      Symbol         [mrb_sym]
    552     d:      Data           [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified
    553     I:      Inline struct  [void*]
    554     &:      Block          [mrb_value]
    555     *:      rest argument  [mrb_value*,mrb_int]   Receive the rest of the arguments as an array.
    556     |:      optional                              Next argument of '|' and later are optional.
    557     ?:      optional given [mrb_bool]             true if preceding argument (optional) is given.
     573    f:      Fixnum/Float   [mrb_float]
     574    i:      Fixnum/Float   [mrb_int]
     575    b:      boolean        [mrb_bool]
     576    n:      String/Symbol  [mrb_sym]
     577    d:      data           [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil
     578    I:      inline struct  [void*]
     579    &:      block          [mrb_value]            &! raises exception if no block given
     580    *:      rest argument  [mrb_value*,mrb_int]   The rest of the arguments as an array; *! avoid copy of the stack
     581    |:      optional                              Following arguments are optional
     582    ?:      optional given [mrb_bool]             true if preceding argument (optional) is given
     583    ':':    keyword args   [mrb_kwargs const]     Get keyword arguments
    558584 */
    559585MRB_API mrb_int
    560586mrb_get_args(mrb_state *mrb, const char *format, ...)
    561587{
     588  const char *fmt = format;
    562589  char c;
    563   int i = 0;
     590  mrb_int i = 0;
    564591  va_list ap;
    565   int argc = mrb->c->ci->argc;
    566   int arg_i = 0;
    567   mrb_bool array_argv;
     592  mrb_int argc = mrb->c->ci->argc;
     593  mrb_value *array_argv = mrb->c->stack+1;
     594  mrb_bool argv_on_stack = argc >= 0;
    568595  mrb_bool opt = FALSE;
     596  mrb_bool opt_skip = TRUE;
    569597  mrb_bool given = TRUE;
    570 
     598  mrb_value kdict;
     599  mrb_bool reqkarg = FALSE;
     600  mrb_int needargc = 0;
     601
     602  if (!argv_on_stack) {
     603    struct RArray *a = mrb_ary_ptr(*array_argv);
     604    array_argv = ARY_PTR(a);
     605    argc = ARY_LEN(a);
     606  }
    571607  va_start(ap, format);
    572   if (argc < 0) {
    573     struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
    574 
    575     argc = a->len;
    576     array_argv = TRUE;
     608
     609#define ARGV array_argv
     610
     611  while ((c = *fmt++)) {
     612    switch (c) {
     613    case '|':
     614      opt = TRUE;
     615      break;
     616    case '*':
     617      opt_skip = FALSE;
     618      if (!reqkarg) reqkarg = strchr(fmt, ':') ? TRUE : FALSE;
     619      goto check_exit;
     620    case '!':
     621      break;
     622    case ':':
     623      reqkarg = TRUE;
     624      /* fall through */
     625    case '&': case '?':
     626      if (opt) opt_skip = FALSE;
     627      break;
     628    default:
     629      if (!opt) needargc ++;
     630      break;
     631    }
     632  }
     633
     634 check_exit:
     635  if (reqkarg && argc > needargc && mrb_hash_p(kdict = ARGV[argc - 1])) {
     636    mrb_hash_check_kdict(mrb, kdict);
     637    argc --;
    577638  }
    578639  else {
    579     array_argv = FALSE;
    580   }
    581 
    582 #define ARGV \
    583   (array_argv ? mrb_ary_ptr(mrb->c->stack[1])->ptr : (mrb->c->stack + 1))
    584 
     640    kdict = mrb_nil_value();
     641  }
     642
     643  opt = FALSE;
     644  i = 0;
    585645  while ((c = *format++)) {
     646    mrb_value *argv = ARGV;
     647    mrb_bool altmode;
     648
    586649    switch (c) {
    587     case '|': case '*': case '&': case '?':
     650    case '|': case '*': case '&': case '?': case ':':
    588651      break;
    589652    default:
     
    599662    }
    600663
     664    if (*format == '!') {
     665      format ++;
     666      altmode = TRUE;
     667    }
     668    else {
     669      altmode = FALSE;
     670    }
     671
    601672    switch (c) {
    602673    case 'o':
     
    606677        p = va_arg(ap, mrb_value*);
    607678        if (i < argc) {
    608           *p = ARGV[arg_i++];
    609           i++;
     679          *p = argv[i++];
    610680        }
    611681      }
     
    619689          mrb_value ss;
    620690
    621           ss = ARGV[arg_i++];
     691          ss = argv[i++];
    622692          if (!class_ptr_p(ss)) {
    623             mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss);
     693            mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss);
    624694          }
    625695          *p = ss;
    626           i++;
    627696        }
    628697      }
     
    633702
    634703        p = va_arg(ap, mrb_value*);
    635         if (*format == '!') {
    636           format++;
    637           if (i < argc && mrb_nil_p(ARGV[arg_i])) {
    638             *p = ARGV[arg_i++];
    639             i++;
    640             break;
     704        if (i < argc) {
     705          *p = argv[i++];
     706          if (!(altmode && mrb_nil_p(*p))) {
     707            mrb_to_str(mrb, *p);
    641708          }
    642         }
    643         if (i < argc) {
    644           *p = to_str(mrb, ARGV[arg_i++]);
    645           i++;
    646709        }
    647710      }
     
    652715
    653716        p = va_arg(ap, mrb_value*);
    654         if (*format == '!') {
    655           format++;
    656           if (i < argc && mrb_nil_p(ARGV[arg_i])) {
    657             *p = ARGV[arg_i++];
    658             i++;
    659             break;
     717        if (i < argc) {
     718          *p = argv[i++];
     719          if (!(altmode && mrb_nil_p(*p))) {
     720            *p = to_ary(mrb, *p);
    660721          }
    661         }
    662         if (i < argc) {
    663           *p = to_ary(mrb, ARGV[arg_i++]);
    664           i++;
    665722        }
    666723      }
     
    671728
    672729        p = va_arg(ap, mrb_value*);
    673         if (*format == '!') {
    674           format++;
    675           if (i < argc && mrb_nil_p(ARGV[arg_i])) {
    676             *p = ARGV[arg_i++];
    677             i++;
    678             break;
     730        if (i < argc) {
     731          *p = argv[i++];
     732          if (!(altmode && mrb_nil_p(*p))) {
     733            *p = to_hash(mrb, *p);
    679734          }
    680         }
    681         if (i < argc) {
    682           *p = to_hash(mrb, ARGV[arg_i++]);
    683           i++;
    684735        }
    685736      }
     
    693744        ps = va_arg(ap, char**);
    694745        pl = va_arg(ap, mrb_int*);
    695         if (*format == '!') {
    696           format++;
    697           if (i < argc && mrb_nil_p(ARGV[arg_i])) {
     746        if (i < argc) {
     747          ss = argv[i++];
     748          if (altmode && mrb_nil_p(ss)) {
    698749            *ps = NULL;
    699750            *pl = 0;
    700             i++; arg_i++;
    701             break;
    702751          }
    703         }
    704         if (i < argc) {
    705           ss = to_str(mrb, ARGV[arg_i++]);
    706           *ps = RSTRING_PTR(ss);
    707           *pl = RSTRING_LEN(ss);
    708           i++;
     752          else {
     753            mrb_to_str(mrb, ss);
     754            *ps = RSTRING_PTR(ss);
     755            *pl = RSTRING_LEN(ss);
     756          }
    709757        }
    710758      }
     
    716764
    717765        ps = va_arg(ap, const char**);
    718         if (*format == '!') {
    719           format++;
    720           if (i < argc && mrb_nil_p(ARGV[arg_i])) {
     766        if (i < argc) {
     767          ss = argv[i++];
     768          if (altmode && mrb_nil_p(ss)) {
    721769            *ps = NULL;
    722             i++; arg_i++;
    723             break;
    724770          }
    725         }
    726         if (i < argc) {
    727           ss = to_str(mrb, ARGV[arg_i++]);
    728           *ps = mrb_string_value_cstr(mrb, &ss);
    729           i++;
     771          else {
     772            mrb_to_str(mrb, ss);
     773            *ps = RSTRING_CSTR(mrb, ss);
     774          }
    730775        }
    731776      }
     
    740785        pb = va_arg(ap, mrb_value**);
    741786        pl = va_arg(ap, mrb_int*);
    742         if (*format == '!') {
    743           format++;
    744           if (i < argc && mrb_nil_p(ARGV[arg_i])) {
     787        if (i < argc) {
     788          aa = argv[i++];
     789          if (altmode && mrb_nil_p(aa)) {
    745790            *pb = 0;
    746791            *pl = 0;
    747             i++; arg_i++;
    748             break;
    749792          }
    750         }
    751         if (i < argc) {
    752           aa = to_ary(mrb, ARGV[arg_i++]);
    753           a = mrb_ary_ptr(aa);
    754           *pb = a->ptr;
    755           *pl = a->len;
    756           i++;
     793          else {
     794            aa = to_ary(mrb, aa);
     795            a = mrb_ary_ptr(aa);
     796            *pb = ARY_PTR(a);
     797            *pl = ARY_LEN(a);
     798          }
    757799        }
    758800      }
     
    765807        p = va_arg(ap, void**);
    766808        if (i < argc) {
    767           ss = ARGV[arg_i];
    768           if (mrb_type(ss) != MRB_TT_ISTRUCT)
     809          ss = argv[i++];
     810          if (!mrb_istruct_p(ss))
    769811          {
    770             mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss);
     812            mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", ss);
    771813          }
    772814          *p = mrb_istruct_ptr(ss);
    773           arg_i++;
    774           i++;
    775         }
    776       }
    777       break;
     815        }
     816      }
     817      break;
     818#ifndef MRB_WITHOUT_FLOAT
    778819    case 'f':
    779820      {
     
    782823        p = va_arg(ap, mrb_float*);
    783824        if (i < argc) {
    784           *p = mrb_to_flo(mrb, ARGV[arg_i]);
    785           arg_i++;
    786           i++;
    787         }
    788       }
    789       break;
     825          *p = mrb_to_flo(mrb, argv[i++]);
     826        }
     827      }
     828      break;
     829#endif
    790830    case 'i':
    791831      {
     
    794834        p = va_arg(ap, mrb_int*);
    795835        if (i < argc) {
    796           switch (mrb_type(ARGV[arg_i])) {
    797             case MRB_TT_FIXNUM:
    798               *p = mrb_fixnum(ARGV[arg_i]);
    799               break;
    800             case MRB_TT_FLOAT:
    801               {
    802                 mrb_float f = mrb_float(ARGV[arg_i]);
    803 
    804                 if (!FIXABLE_FLOAT(f)) {
    805                   mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
    806                 }
    807                 *p = (mrb_int)f;
    808               }
    809               break;
    810             case MRB_TT_STRING:
    811               mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer");
    812               break;
    813             default:
    814               *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
    815               break;
    816           }
    817           arg_i++;
    818           i++;
     836          *p = mrb_fixnum(mrb_to_int(mrb, argv[i++]));
    819837        }
    820838      }
     
    825843
    826844        if (i < argc) {
    827           mrb_value b = ARGV[arg_i++];
     845          mrb_value b = argv[i++];
    828846          *boolp = mrb_test(b);
    829           i++;
    830847        }
    831848      }
     
    839856          mrb_value ss;
    840857
    841           ss = ARGV[arg_i++];
     858          ss = argv[i++];
    842859          *symp = to_sym(mrb, ss);
    843           i++;
    844860        }
    845861      }
     
    852868        datap = va_arg(ap, void**);
    853869        type = va_arg(ap, struct mrb_data_type const*);
    854         if (*format == '!') {
    855           format++;
    856           if (i < argc && mrb_nil_p(ARGV[arg_i])) {
     870        if (i < argc) {
     871          mrb_value dd = argv[i++];
     872          if (altmode && mrb_nil_p(dd)) {
    857873            *datap = 0;
    858             i++; arg_i++;
    859             break;
    860874          }
    861         }
    862         if (i < argc) {
    863           *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type);
    864           ++i;
     875          else {
     876            *datap = mrb_data_get_ptr(mrb, dd, type);
     877          }
    865878        }
    866879      }
     
    878891          bp = mrb->c->stack + mrb->c->ci->argc + 1;
    879892        }
     893        if (altmode && mrb_nil_p(*bp)) {
     894          mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
     895        }
    880896        *p = *bp;
    881897      }
    882898      break;
    883899    case '|':
     900      if (opt_skip && i == argc) goto finish;
    884901      opt = TRUE;
    885902      break;
     
    897914        mrb_value **var;
    898915        mrb_int *pl;
     916        mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE;
    899917
    900918        var = va_arg(ap, mrb_value**);
     
    903921          *pl = argc-i;
    904922          if (*pl > 0) {
    905             *var = ARGV + arg_i;
     923            if (nocopy) {
     924              *var = argv+i;
     925            }
     926            else {
     927              mrb_value args = mrb_ary_new_from_values(mrb, *pl, argv+i);
     928              RARRAY(args)->c = NULL;
     929              *var = RARRAY_PTR(args);
     930            }
    906931          }
    907932          i = argc;
    908           arg_i += *pl;
    909933        }
    910934        else {
     
    914938      }
    915939      break;
     940
     941    case ':':
     942      {
     943        mrb_value ksrc = mrb_hash_p(kdict) ? mrb_hash_dup(mrb, kdict) : mrb_hash_new(mrb);
     944        const mrb_kwargs *kwargs = va_arg(ap, const mrb_kwargs*);
     945        mrb_value *rest;
     946
     947        if (kwargs == NULL) {
     948          rest = NULL;
     949        }
     950        else {
     951          uint32_t kwnum = kwargs->num;
     952          uint32_t required = kwargs->required;
     953          const char *const *kname = kwargs->table;
     954          mrb_value *values = kwargs->values;
     955          uint32_t j;
     956          const uint32_t keyword_max = 40;
     957
     958          if (kwnum > keyword_max || required > kwnum) {
     959            mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large");
     960          }
     961
     962          for (j = required; j > 0; j --, kname ++, values ++) {
     963            mrb_value k = mrb_symbol_value(mrb_intern_cstr(mrb, *kname));
     964            if (!mrb_hash_key_p(mrb, ksrc, k)) {
     965              mrb_raisef(mrb, E_ARGUMENT_ERROR, "missing keyword: %s", *kname);
     966            }
     967            *values = mrb_hash_delete_key(mrb, ksrc, k);
     968            mrb_gc_protect(mrb, *values);
     969          }
     970
     971          for (j = kwnum - required; j > 0; j --, kname ++, values ++) {
     972            mrb_value k = mrb_symbol_value(mrb_intern_cstr(mrb, *kname));
     973            if (mrb_hash_key_p(mrb, ksrc, k)) {
     974              *values = mrb_hash_delete_key(mrb, ksrc, k);
     975              mrb_gc_protect(mrb, *values);
     976            }
     977            else {
     978              *values = mrb_undef_value();
     979            }
     980          }
     981
     982          rest = kwargs->rest;
     983        }
     984
     985        if (rest) {
     986          *rest = ksrc;
     987        }
     988        else if (!mrb_hash_empty_p(mrb, ksrc)) {
     989          ksrc = mrb_hash_keys(mrb, ksrc);
     990          ksrc = RARRAY_PTR(ksrc)[0];
     991          mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown keyword: %v", ksrc);
     992        }
     993      }
     994      break;
     995
    916996    default:
    917       mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1));
     997      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c);
    918998      break;
    919999    }
     
    9251005    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
    9261006  }
     1007
     1008finish:
    9271009  va_end(ap);
    9281010  return i;
     
    9831065    int superclass_seen = 0;
    9841066
    985     if (m->flags & MRB_FLAG_IS_PREPENDED)
     1067    if (m->flags & MRB_FL_CLASS_IS_PREPENDED)
    9861068      goto skip;
    9871069
     
    9901072
    9911073    p = c->super;
    992     while(p) {
     1074    while (p) {
    9931075      if (p->tt == MRB_TT_ICLASS) {
    9941076        if (p->mt == m->mt) {
     
    10061088
    10071089    ic = include_class_new(mrb, m, ins_pos->super);
     1090    m->flags |= MRB_FL_CLASS_IS_INHERITED;
    10081091    ins_pos->super = ic;
    1009     mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ins_pos->super);
     1092    mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
     1093    mrb_mc_clear_by_class(mrb, ins_pos);
    10101094    ins_pos = ic;
    10111095  skip:
    10121096    m = m->super;
    10131097  }
     1098  mc_clear_all(mrb);
    10141099  return 0;
    10151100}
     
    10181103mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
    10191104{
    1020   int changed = include_module_at(mrb, c, find_origin(c), m, 1);
    1021   if (changed < 0) {
     1105  mrb_check_frozen(mrb, c);
     1106  if (include_module_at(mrb, c, find_origin(c), m, 1) < 0) {
    10221107    mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
    10231108  }
     
    10301115  int changed = 0;
    10311116
    1032   if (!(c->flags & MRB_FLAG_IS_PREPENDED)) {
     1117  mrb_check_frozen(mrb, c);
     1118  if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
    10331119    origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c);
    1034     origin->flags |= MRB_FLAG_IS_ORIGIN;
     1120    origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED;
    10351121    origin->super = c->super;
    10361122    c->super = origin;
     
    10381124    c->mt = kh_init(mt, mrb);
    10391125    mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin);
    1040     c->flags |= MRB_FLAG_IS_PREPENDED;
     1126    c->flags |= MRB_FL_CLASS_IS_PREPENDED;
    10411127  }
    10421128  changed = include_module_at(mrb, c, c, m, 0);
     
    11151201      mrb_ary_push(mrb, result, mrb_obj_value(c->c));
    11161202    }
    1117     else if (!(c->flags & MRB_FLAG_IS_PREPENDED)) {
     1203    else if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
    11181204      mrb_ary_push(mrb, result, mrb_obj_value(c));
    11191205    }
     
    11331219  mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod));
    11341220  return mod;
    1135 }
    1136 
    1137 static mrb_value
    1138 mrb_mod_included_modules(mrb_state *mrb, mrb_value self)
    1139 {
    1140   mrb_value result;
    1141   struct RClass *c = mrb_class_ptr(self);
    1142   struct RClass *origin = c;
    1143 
    1144   MRB_CLASS_ORIGIN(origin);
    1145   result = mrb_ary_new(mrb);
    1146   while (c) {
    1147     if (c != origin && c->tt == MRB_TT_ICLASS) {
    1148       if (c->c->tt == MRB_TT_MODULE) {
    1149         mrb_ary_push(mrb, result, mrb_obj_value(c->c));
    1150       }
    1151     }
    1152     c = c->super;
    1153   }
    1154 
    1155   return result;
    11561221}
    11571222
     
    11671232  }
    11681233  return mod;
    1169 }
    1170 
    1171 mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int);
    1172 
    1173 /* 15.2.2.4.33 */
    1174 /*
    1175  *  call-seq:
    1176  *     mod.instance_methods(include_super=true)   -> array
    1177  *
    1178  *  Returns an array containing the names of the public and protected instance
    1179  *  methods in the receiver. For a module, these are the public and protected methods;
    1180  *  for a class, they are the instance (not singleton) methods. With no
    1181  *  argument, or with an argument that is <code>false</code>, the
    1182  *  instance methods in <i>mod</i> are returned, otherwise the methods
    1183  *  in <i>mod</i> and <i>mod</i>'s superclasses are returned.
    1184  *
    1185  *     module A
    1186  *       def method1()  end
    1187  *     end
    1188  *     class B
    1189  *       def method2()  end
    1190  *     end
    1191  *     class C < B
    1192  *       def method3()  end
    1193  *     end
    1194  *
    1195  *     A.instance_methods                #=> [:method1]
    1196  *     B.instance_methods(false)         #=> [:method2]
    1197  *     C.instance_methods(false)         #=> [:method3]
    1198  *     C.instance_methods(true).length   #=> 43
    1199  */
    1200 
    1201 static mrb_value
    1202 mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod)
    1203 {
    1204   struct RClass *c = mrb_class_ptr(mod);
    1205   mrb_bool recur = TRUE;
    1206   mrb_get_args(mrb, "|b", &recur);
    1207   return mrb_class_instance_method_list(mrb, recur, c, 0);
    12081234}
    12091235
     
    12331259  case MRB_TT_SYMBOL:
    12341260  case MRB_TT_FIXNUM:
     1261#ifndef MRB_WITHOUT_FLOAT
    12351262  case MRB_TT_FLOAT:
     1263#endif
    12361264    mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
    12371265    return mrb_nil_value();    /* not reached */
     
    12641292}
    12651293
    1266 MRB_API struct RProc*
     1294#ifdef MRB_METHOD_CACHE
     1295static void
     1296mc_clear_all(mrb_state *mrb)
     1297{
     1298  struct mrb_cache_entry *mc = mrb->cache;
     1299  int i;
     1300
     1301  for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
     1302    mc[i].c = 0;
     1303  }
     1304}
     1305
     1306void
     1307mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c)
     1308{
     1309  struct mrb_cache_entry *mc = mrb->cache;
     1310  int i;
     1311
     1312  if (c->flags & MRB_FL_CLASS_IS_INHERITED) {
     1313    mc_clear_all(mrb);
     1314    c->flags &= ~MRB_FL_CLASS_IS_INHERITED;
     1315    return;
     1316  }
     1317  for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
     1318    if (mc[i].c == c) mc[i].c = 0;
     1319  }
     1320}
     1321
     1322static void
     1323mc_clear_by_id(mrb_state *mrb, struct RClass *c, mrb_sym mid)
     1324{
     1325  struct mrb_cache_entry *mc = mrb->cache;
     1326  int i;
     1327
     1328  if (c->flags & MRB_FL_CLASS_IS_INHERITED) {
     1329    mc_clear_all(mrb);
     1330    c->flags &= ~MRB_FL_CLASS_IS_INHERITED;
     1331    return;
     1332  }
     1333  for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
     1334    if (mc[i].c == c || mc[i].mid == mid)
     1335      mc[i].c = 0;
     1336  }
     1337}
     1338#endif
     1339
     1340MRB_API mrb_method_t
    12671341mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
    12681342{
    12691343  khiter_t k;
    1270   struct RProc *m;
     1344  mrb_method_t m;
    12711345  struct RClass *c = *cp;
     1346#ifdef MRB_METHOD_CACHE
     1347  struct RClass *oc = c;
     1348  int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
     1349  struct mrb_cache_entry *mc = &mrb->cache[h];
     1350
     1351  if (mc->c == c && mc->mid == mid) {
     1352    *cp = mc->c0;
     1353    return mc->m;
     1354  }
     1355#endif
    12721356
    12731357  while (c) {
     
    12781362      if (k != kh_end(h)) {
    12791363        m = kh_value(h, k);
    1280         if (!m) break;
     1364        if (MRB_METHOD_UNDEF_P(m)) break;
    12811365        *cp = c;
     1366#ifdef MRB_METHOD_CACHE
     1367        mc->c = oc;
     1368        mc->c0 = c;
     1369        mc->mid = mid;
     1370        mc->m = m;
     1371#endif
    12821372        return m;
    12831373      }
     
    12851375    c = c->super;
    12861376  }
    1287   return NULL;                  /* no method */
    1288 }
    1289 
    1290 MRB_API struct RProc*
     1377  MRB_METHOD_FROM_PROC(m, NULL);
     1378  return m;                  /* no method */
     1379}
     1380
     1381MRB_API mrb_method_t
    12911382mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
    12921383{
    1293   struct RProc *m;
     1384  mrb_method_t m;
    12941385
    12951386  m = mrb_method_search_vm(mrb, &c, mid);
    1296   if (!m) {
    1297     mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0);
    1298     if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) {
    1299       inspect = mrb_any_to_s(mrb, mrb_obj_value(c));
    1300     }
    1301     mrb_name_error(mrb, mid, "undefined method '%S' for class %S",
    1302                mrb_sym2str(mrb, mid), inspect);
     1387  if (MRB_METHOD_UNDEF_P(m)) {
     1388    mrb_name_error(mrb, mid, "undefined method '%n' for class %C", mid, c);
    13031389  }
    13041390  return m;
    13051391}
    13061392
    1307 static mrb_value
    1308 attr_reader(mrb_state *mrb, mrb_value obj)
    1309 {
    1310   mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
    1311   return mrb_iv_get(mrb, obj, to_sym(mrb, name));
    1312 }
    1313 
    1314 static mrb_value
    1315 mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
     1393#define ONSTACK_ALLOC_MAX 32
     1394
     1395static mrb_sym
     1396prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char *suffix)
     1397{
     1398  char onstack[ONSTACK_ALLOC_MAX];
     1399  mrb_int sym_len;
     1400  const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len);
     1401  size_t prefix_len = prefix ? strlen(prefix) : 0;
     1402  size_t suffix_len = suffix ? strlen(suffix) : 0;
     1403  size_t name_len = sym_len + prefix_len + suffix_len;
     1404  char *buf = name_len > sizeof(onstack) ? (char *)mrb_alloca(mrb, name_len) : onstack;
     1405  char *p = buf;
     1406
     1407  if (prefix_len > 0) {
     1408    memcpy(p, prefix, prefix_len);
     1409    p += prefix_len;
     1410  }
     1411
     1412  memcpy(p, sym_str, sym_len);
     1413  p += sym_len;
     1414
     1415  if (suffix_len > 0) {
     1416    memcpy(p, suffix, suffix_len);
     1417    p += suffix_len;
     1418  }
     1419
     1420  return mrb_intern(mrb, buf, name_len);
     1421}
     1422
     1423static mrb_value
     1424prepare_ivar_name(mrb_state *mrb, mrb_sym sym)
     1425{
     1426  sym = prepare_name_common(mrb, sym, "@", NULL);
     1427  mrb_iv_name_sym_check(mrb, sym);
     1428  return mrb_symbol_value(sym);
     1429}
     1430
     1431static mrb_sym
     1432prepare_writer_name(mrb_state *mrb, mrb_sym sym)
     1433{
     1434  return prepare_name_common(mrb, sym, NULL, "=");
     1435}
     1436
     1437static mrb_value
     1438mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state *, mrb_value), mrb_sym (*access_name)(mrb_state *, mrb_sym))
    13161439{
    13171440  struct RClass *c = mrb_class_ptr(mod);
     
    13231446  ai = mrb_gc_arena_save(mrb);
    13241447  for (i=0; i<argc; i++) {
    1325     mrb_value name, str;
    1326     mrb_sym method, sym;
     1448    mrb_value name;
     1449    mrb_sym method;
     1450    struct RProc *p;
     1451    mrb_method_t m;
    13271452
    13281453    method = to_sym(mrb, argv[i]);
    1329     name = mrb_sym2str(mrb, method);
    1330     str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1);
    1331     mrb_str_cat_lit(mrb, str, "@");
    1332     mrb_str_cat_str(mrb, str, name);
    1333     sym = mrb_intern_str(mrb, str);
    1334     mrb_iv_check(mrb, sym);
    1335     name = mrb_symbol_value(sym);
    1336     mrb_define_method_raw(mrb, c, method,
    1337                           mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name));
     1454    name = prepare_ivar_name(mrb, method);
     1455    if (access_name) {
     1456      method = access_name(mrb, method);
     1457    }
     1458
     1459    p = mrb_proc_new_cfunc_with_env(mrb, accessor, 1, &name);
     1460    MRB_METHOD_FROM_PROC(m, p);
     1461    mrb_define_method_raw(mrb, c, method, m);
    13381462    mrb_gc_arena_restore(mrb, ai);
    13391463  }
    13401464  return mrb_nil_value();
     1465}
     1466
     1467static mrb_value
     1468attr_reader(mrb_state *mrb, mrb_value obj)
     1469{
     1470  mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
     1471  return mrb_iv_get(mrb, obj, to_sym(mrb, name));
     1472}
     1473
     1474static mrb_value
     1475mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
     1476{
     1477  return mod_attr_define(mrb, mod, attr_reader, NULL);
    13411478}
    13421479
     
    13551492mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
    13561493{
    1357   struct RClass *c = mrb_class_ptr(mod);
    1358   mrb_value *argv;
    1359   mrb_int argc, i;
    1360   int ai;
    1361 
    1362   mrb_get_args(mrb, "*", &argv, &argc);
    1363   ai = mrb_gc_arena_save(mrb);
    1364   for (i=0; i<argc; i++) {
    1365     mrb_value name, str, attr;
    1366     mrb_sym method, sym;
    1367 
    1368     method = to_sym(mrb, argv[i]);
    1369 
    1370     /* prepare iv name (@name) */
    1371     name = mrb_sym2str(mrb, method);
    1372     str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1);
    1373     mrb_str_cat_lit(mrb, str, "@");
    1374     mrb_str_cat_str(mrb, str, name);
    1375     sym = mrb_intern_str(mrb, str);
    1376     mrb_iv_check(mrb, sym);
    1377     attr = mrb_symbol_value(sym);
    1378 
    1379     /* prepare method name (name=) */
    1380     str = mrb_str_buf_new(mrb, RSTRING_LEN(str));
    1381     mrb_str_cat_str(mrb, str, name);
    1382     mrb_str_cat_lit(mrb, str, "=");
    1383     method = mrb_intern_str(mrb, str);
    1384 
    1385     mrb_define_method_raw(mrb, c, method,
    1386                           mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr));
    1387     mrb_gc_arena_restore(mrb, ai);
    1388   }
    1389   return mrb_nil_value();
     1494  return mod_attr_define(mrb, mod, attr_writer, prepare_writer_name);
    13901495}
    13911496
     
    14021507  if (ttype == 0) ttype = MRB_TT_OBJECT;
    14031508  if (ttype <= MRB_TT_CPTR) {
    1404     mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv);
     1509    mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv);
    14051510  }
    14061511  o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
     
    14201525 */
    14211526
    1422 MRB_API mrb_value
     1527mrb_value
    14231528mrb_instance_new(mrb_state *mrb, mrb_value cv)
    14241529{
     
    14261531  mrb_value *argv;
    14271532  mrb_int argc;
    1428 
    1429   mrb_get_args(mrb, "*&", &argv, &argc, &blk);
     1533  mrb_sym init;
     1534
     1535  mrb_get_args(mrb, "*!&", &argv, &argc, &blk);
    14301536  obj = mrb_instance_alloc(mrb, cv);
    1431   mrb_funcall_with_block(mrb, obj, mrb_intern_lit(mrb, "initialize"), argc, argv, blk);
    1432 
     1537  init = mrb_intern_lit(mrb, "initialize");
     1538  if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) {
     1539    mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
     1540  }
    14331541  return obj;
    14341542}
     
    14741582  new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
    14751583  mid = mrb_intern_lit(mrb, "initialize");
    1476   if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) {
     1584  if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) {
     1585    mrb_class_initialize(mrb, new_class);
     1586  }
     1587  else {
    14771588    mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
    14781589  }
     
    15591670mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid)
    15601671{
    1561   khiter_t k;
    1562 
    1563   while (c) {
    1564     khash_t(mt) *h = c->mt;
    1565 
    1566     if (h) {
    1567       k = kh_get(mt, mrb, h, mid);
    1568       if (k != kh_end(h)) {
    1569         if (kh_value(h, k)) {
    1570           return TRUE;  /* method exists */
    1571         }
    1572         else {
    1573           return FALSE; /* undefined method */
    1574         }
    1575       }
    1576     }
    1577     c = c->super;
    1578   }
    1579   return FALSE;         /* no method */
     1672  mrb_method_t m;
     1673
     1674  m = mrb_method_search_vm(mrb, &c, mid);
     1675  if (MRB_METHOD_UNDEF_P(m)) {
     1676    return FALSE;
     1677  }
     1678  return TRUE;
    15801679}
    15811680
     
    15901689{
    15911690  mrb_value path;
    1592   const char *name;
    1593   mrb_sym classpath = mrb_intern_lit(mrb, "__classpath__");
    1594 
    1595   path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath);
     1691  mrb_sym nsym = mrb_intern_lit(mrb, "__classname__");
     1692
     1693  path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym);
    15961694  if (mrb_nil_p(path)) {
    1597     struct RClass *outer = mrb_class_outer_module(mrb, c);
    1598     mrb_sym sym = mrb_class_sym(mrb, c, outer);
    1599     mrb_int len;
    1600 
    1601     if (sym == 0) {
    1602       return mrb_nil_value();
    1603     }
    1604     else if (outer && outer != c && outer != mrb->object_class) {
    1605       mrb_value base = mrb_class_path(mrb, outer);
    1606       path = mrb_str_buf_new(mrb, 0);
    1607       if (mrb_nil_p(base)) {
    1608         mrb_str_cat_lit(mrb, path, "#<Class:");
    1609         mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, outer));
    1610         mrb_str_cat_lit(mrb, path, ">");
    1611       }
    1612       else {
    1613         mrb_str_concat(mrb, path, base);
    1614       }
    1615       mrb_str_cat_lit(mrb, path, "::");
    1616       name = mrb_sym2name_len(mrb, sym, &len);
    1617       mrb_str_cat(mrb, path, name, len);
    1618     }
    1619     else {
    1620       name = mrb_sym2name_len(mrb, sym, &len);
    1621       path = mrb_str_new(mrb, name, len);
    1622     }
    1623     if (!MRB_FROZEN_P(c)) {
    1624       mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path);
    1625     }
     1695    /* no name (yet) */
     1696    return mrb_class_find_path(mrb, c);
     1697  }
     1698  else if (mrb_symbol_p(path)) {
     1699    /* toplevel class/module */
     1700    return mrb_sym_str(mrb, mrb_symbol(path));
    16261701  }
    16271702  return mrb_str_dup(mrb, path);
    16281703}
    16291704
    1630 MRB_API struct RClass *
     1705MRB_API struct RClass*
    16311706mrb_class_real(struct RClass* cl)
    16321707{
    1633   if (cl == 0)
    1634     return NULL;
     1708  if (cl == 0) return NULL;
    16351709  while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) {
    16361710    cl = cl->super;
     1711    if (cl == 0) return NULL;
    16371712  }
    16381713  return cl;
     
    16421717mrb_class_name(mrb_state *mrb, struct RClass* c)
    16431718{
    1644   mrb_value path = mrb_class_path(mrb, c);
    1645   if (mrb_nil_p(path)) {
    1646     path = mrb_str_new_lit(mrb, "#<Class:");
    1647     mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c));
    1648     mrb_str_cat_lit(mrb, path, ">");
    1649   }
    1650   return RSTRING_PTR(path);
     1719  mrb_value name = class_name_str(mrb, c);
     1720  return RSTRING_PTR(name);
    16511721}
    16521722
     
    16671737{
    16681738  if (super->tt != MRB_TT_CLASS) {
    1669     mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super));
     1739    mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%C given)", super);
    16701740  }
    16711741  if (super->tt == MRB_TT_SCLASS) {
     
    17341804mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
    17351805{
    1736   struct RProc *m = mrb_method_search(mrb, c, b);
    1737 
     1806  mrb_method_t m = mrb_method_search(mrb, c, b);
     1807
     1808  if (!MRB_METHOD_CFUNC_P(m)) {
     1809    struct RProc *p = MRB_METHOD_PROC(m);
     1810
     1811    if (MRB_PROC_ENV_P(p)) {
     1812      MRB_PROC_ENV(p)->mid = b;
     1813    }
     1814    else {
     1815      struct RClass *tc = MRB_PROC_TARGET_CLASS(p);
     1816      struct REnv *e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
     1817
     1818      e->mid = b;
     1819      if (tc) {
     1820        e->c = tc;
     1821        mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc);
     1822      }
     1823      p->e.env = e;
     1824      p->flags |= MRB_PROC_ENVSET;
     1825    }
     1826  }
    17381827  mrb_define_method_raw(mrb, c, a, m);
    17391828}
     
    17411830/*!
    17421831 * Defines an alias of a method.
     1832 * \param mrb    the mruby state
    17431833 * \param klass  the class which the original method belongs to
    17441834 * \param name1  a new name for the method
     
    17601850 */
    17611851
    1762 static mrb_value
     1852mrb_value
    17631853mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
    17641854{
    1765   mrb_value str;
    1766 
    1767   if (mrb_type(klass) == MRB_TT_SCLASS) {
     1855
     1856  if (mrb_sclass_p(klass)) {
    17681857    mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__"));
    1769 
    1770     str = mrb_str_new_lit(mrb, "#<Class:");
     1858    mrb_value str = mrb_str_new_lit(mrb, "#<Class:");
    17711859
    17721860    if (class_ptr_p(v)) {
     
    17791867  }
    17801868  else {
    1781     struct RClass *c;
    1782     mrb_value path;
    1783 
    1784     str = mrb_str_buf_new(mrb, 32);
    1785     c = mrb_class_ptr(klass);
    1786     path = mrb_class_path(mrb, c);
    1787 
    1788     if (mrb_nil_p(path)) {
    1789       switch (mrb_type(klass)) {
    1790         case MRB_TT_CLASS:
    1791           mrb_str_cat_lit(mrb, str, "#<Class:");
    1792           break;
    1793 
    1794         case MRB_TT_MODULE:
    1795           mrb_str_cat_lit(mrb, str, "#<Module:");
    1796           break;
    1797 
    1798         default:
    1799           /* Shouldn't be happened? */
    1800           mrb_str_cat_lit(mrb, str, "#<??????:");
    1801           break;
    1802       }
    1803       mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c));
    1804       return mrb_str_cat_lit(mrb, str, ">");
    1805     }
    1806     else {
    1807       return path;
    1808     }
     1869    return class_name_str(mrb, mrb_class_ptr(klass));
    18091870  }
    18101871}
     
    18181879  mrb_get_args(mrb, "nn", &new_name, &old_name);
    18191880  mrb_alias_method(mrb, c, new_name, old_name);
    1820   return mrb_nil_value();
     1881  return mod;
    18211882}
    18221883
     
    18241885undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
    18251886{
     1887  mrb_method_t m;
     1888
     1889  MRB_METHOD_FROM_PROC(m, NULL);
     1890  mrb_define_method_raw(mrb, c, a, m);
     1891}
     1892
     1893void
     1894mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a)
     1895{
    18261896  if (!mrb_obj_respond_to(mrb, c, a)) {
    1827     mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c));
    1828   }
    1829   else {
    1830     mrb_define_method_raw(mrb, c, a, NULL);
    1831   }
     1897    mrb_name_error(mrb, a, "undefined method '%n' for class '%C'", a, c);
     1898  }
     1899  undef_method(mrb, c, a);
    18321900}
    18331901
     
    18531921  mrb_get_args(mrb, "*", &argv, &argc);
    18541922  while (argc--) {
    1855     undef_method(mrb, c, to_sym(mrb, *argv));
     1923    mrb_undef_method_id(mrb, c, to_sym(mrb, *argv));
    18561924    argv++;
    18571925  }
     
    18591927}
    18601928
    1861 static mrb_value
    1862 mod_define_method(mrb_state *mrb, mrb_value self)
    1863 {
    1864   struct RClass *c = mrb_class_ptr(self);
    1865   struct RProc *p;
    1866   mrb_sym mid;
    1867   mrb_value proc = mrb_undef_value();
    1868   mrb_value blk;
    1869 
    1870   mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
    1871   switch (mrb_type(proc)) {
    1872     case MRB_TT_PROC:
    1873       blk = proc;
    1874       break;
    1875     case MRB_TT_UNDEF:
    1876       /* ignored */
    1877       break;
    1878     default:
    1879       mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc)));
    1880       break;
    1881   }
    1882   if (mrb_nil_p(blk)) {
    1883     mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    1884   }
    1885   p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
    1886   mrb_proc_copy(p, mrb_proc_ptr(blk));
    1887   p->flags |= MRB_PROC_STRICT;
    1888   mrb_define_method_raw(mrb, c, mid, p);
    1889   return mrb_symbol_value(mid);
    1890 }
    1891 
    18921929static void
    1893 check_cv_name_str(mrb_state *mrb, mrb_value str)
    1894 {
    1895   const char *s = RSTRING_PTR(str);
    1896   mrb_int len = RSTRING_LEN(str);
    1897 
    1898   if (len < 3 || !(s[0] == '@' && s[1] == '@')) {
    1899     mrb_name_error(mrb, mrb_intern_str(mrb, str), "'%S' is not allowed as a class variable name", str);
    1900   }
    1901 }
    1902 
    1903 static void
    1904 check_cv_name_sym(mrb_state *mrb, mrb_sym id)
    1905 {
    1906   check_cv_name_str(mrb, mrb_sym2str(mrb, id));
    1907 }
    1908 
    1909 /* 15.2.2.4.16 */
    1910 /*
    1911  *  call-seq:
    1912  *     obj.class_variable_defined?(symbol)    -> true or false
    1913  *
    1914  *  Returns <code>true</code> if the given class variable is defined
    1915  *  in <i>obj</i>.
    1916  *
    1917  *     class Fred
    1918  *       @@foo = 99
    1919  *     end
    1920  *     Fred.class_variable_defined?(:@@foo)    #=> true
    1921  *     Fred.class_variable_defined?(:@@bar)    #=> false
    1922  */
    1923 
    1924 static mrb_value
    1925 mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod)
     1930check_const_name_sym(mrb_state *mrb, mrb_sym id)
     1931{
     1932  mrb_int len;
     1933  const char *name = mrb_sym_name_len(mrb, id, &len);
     1934  if (!mrb_const_name_p(mrb, name, len)) {
     1935    mrb_name_error(mrb, id, "wrong constant name %n", id);
     1936  }
     1937}
     1938
     1939static mrb_value
     1940mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
    19261941{
    19271942  mrb_sym id;
     1943  mrb_bool inherit = TRUE;
     1944
     1945  mrb_get_args(mrb, "n|b", &id, &inherit);
     1946  check_const_name_sym(mrb, id);
     1947  if (inherit) {
     1948    return mrb_bool_value(mrb_const_defined(mrb, mod, id));
     1949  }
     1950  return mrb_bool_value(mrb_const_defined_at(mrb, mod, id));
     1951}
     1952
     1953static mrb_value
     1954mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id)
     1955{
     1956  check_const_name_sym(mrb, id);
     1957  return mrb_const_get(mrb, mod, id);
     1958}
     1959
     1960static mrb_value
     1961mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
     1962{
     1963  mrb_value path;
     1964  mrb_sym id;
     1965  char *ptr;
     1966  mrb_int off, end, len;
     1967
     1968  mrb_get_args(mrb, "o", &path);
     1969
     1970  if (mrb_symbol_p(path)) {
     1971    /* const get with symbol */
     1972    id = mrb_symbol(path);
     1973    return mrb_const_get_sym(mrb, mod, id);
     1974  }
     1975
     1976  /* const get with class path string */
     1977  path = mrb_ensure_string_type(mrb, path);
     1978  ptr = RSTRING_PTR(path);
     1979  len = RSTRING_LEN(path);
     1980  off = 0;
     1981
     1982  while (off < len) {
     1983    end = mrb_str_index_lit(mrb, path, "::", off);
     1984    end = (end == -1) ? len : end;
     1985    id = mrb_intern(mrb, ptr+off, end-off);
     1986    mod = mrb_const_get_sym(mrb, mod, id);
     1987    if (end == len)
     1988      off = end;
     1989    else {
     1990      off = end + 2;
     1991      if (off == len) {         /* trailing "::" */
     1992        mrb_name_error(mrb, id, "wrong constant name '%v'", path);
     1993      }
     1994    }
     1995  }
     1996
     1997  return mod;
     1998}
     1999
     2000static mrb_value
     2001mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
     2002{
     2003  mrb_sym id;
     2004  mrb_value value;
     2005
     2006  mrb_get_args(mrb, "no", &id, &value);
     2007  check_const_name_sym(mrb, id);
     2008  mrb_const_set(mrb, mod, id, value);
     2009  return value;
     2010}
     2011
     2012static mrb_value
     2013mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
     2014{
     2015  mrb_sym id;
     2016  mrb_value val;
    19282017
    19292018  mrb_get_args(mrb, "n", &id);
    1930   check_cv_name_sym(mrb, id);
    1931   return mrb_bool_value(mrb_cv_defined(mrb, mod, id));
    1932 }
    1933 
    1934 /* 15.2.2.4.17 */
    1935 /*
    1936  *  call-seq:
    1937  *     mod.class_variable_get(symbol)    -> obj
    1938  *
    1939  *  Returns the value of the given class variable (or throws a
    1940  *  <code>NameError</code> exception). The <code>@@</code> part of the
    1941  *  variable name should be included for regular class variables
    1942  *
    1943  *     class Fred
    1944  *       @@foo = 99
    1945  *     end
    1946  *     Fred.class_variable_get(:@@foo)     #=> 99
    1947  */
    1948 
    1949 static mrb_value
    1950 mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod)
    1951 {
    1952   mrb_sym id;
    1953 
    1954   mrb_get_args(mrb, "n", &id);
    1955   check_cv_name_sym(mrb, id);
    1956   return mrb_cv_get(mrb, mod, id);
    1957 }
    1958 
    1959 /* 15.2.2.4.18 */
    1960 /*
    1961  *  call-seq:
    1962  *     obj.class_variable_set(symbol, obj)    -> obj
    1963  *
    1964  *  Sets the class variable names by <i>symbol</i> to
    1965  *  <i>object</i>.
    1966  *
    1967  *     class Fred
    1968  *       @@foo = 99
    1969  *       def foo
    1970  *         @@foo
    1971  *       end
    1972  *     end
    1973  *     Fred.class_variable_set(:@@foo, 101)     #=> 101
    1974  *     Fred.new.foo                             #=> 101
    1975  */
    1976 
    1977 static mrb_value
    1978 mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod)
    1979 {
    1980   mrb_value value;
    1981   mrb_sym id;
    1982 
    1983   mrb_get_args(mrb, "no", &id, &value);
    1984   check_cv_name_sym(mrb, id);
    1985   mrb_cv_set(mrb, mod, id, value);
    1986   return value;
    1987 }
    1988 
    1989 /* 15.2.2.4.39 */
    1990 /*
    1991  *  call-seq:
    1992  *     remove_class_variable(sym)    -> obj
    1993  *
    1994  *  Removes the definition of the <i>sym</i>, returning that
    1995  *  constant's value.
    1996  *
    1997  *     class Dummy
    1998  *       @@var = 99
    1999  *       puts @@var
    2000  *       p class_variables
    2001  *       remove_class_variable(:@@var)
    2002  *       p class_variables
    2003  *     end
    2004  *
    2005  *  <em>produces:</em>
    2006  *
    2007  *     99
    2008  *     [:@@var]
    2009  *     []
    2010  */
    2011 
    2012 static mrb_value
    2013 mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
    2014 {
    2015   mrb_value val;
    2016   mrb_sym id;
    2017 
    2018   mrb_get_args(mrb, "n", &id);
    2019   check_cv_name_sym(mrb, id);
    2020 
     2019  check_const_name_sym(mrb, id);
    20212020  val = mrb_iv_remove(mrb, mod, id);
    2022   if (!mrb_undef_p(val)) return val;
    2023 
    2024   if (mrb_cv_defined(mrb, mod, id)) {
    2025     mrb_name_error(mrb, id, "cannot remove %S for %S",
    2026                    mrb_sym2str(mrb, id), mod);
    2027   }
    2028 
    2029   mrb_name_error(mrb, id, "class variable %S not defined for %S",
    2030                  mrb_sym2str(mrb, id), mod);
    2031 
    2032  /* not reached */
    2033  return mrb_nil_value();
     2021  if (mrb_undef_p(val)) {
     2022    mrb_name_error(mrb, id, "constant %n not defined", id);
     2023  }
     2024  return val;
     2025}
     2026
     2027static mrb_value
     2028mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
     2029{
     2030  mrb_sym sym;
     2031
     2032  mrb_get_args(mrb, "n", &sym);
     2033
     2034  if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
     2035    mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym);
     2036  }
     2037  else {
     2038    mrb_name_error(mrb, sym, "uninitialized constant %n", sym);
     2039  }
     2040  /* not reached */
     2041  return mrb_nil_value();
    20342042}
    20352043
     
    20702078}
    20712079
    2072 static void
    2073 remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid)
    2074 {
    2075   struct RClass *c = mrb_class_ptr(mod);
    2076   khash_t(mt) *h = find_origin(c)->mt;
    2077   khiter_t k;
    2078 
    2079   if (h) {
    2080     k = kh_get(mt, mrb, h, mid);
    2081     if (k != kh_end(h)) {
    2082       kh_del(mt, mrb, h, k);
    2083       mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid));
    2084       return;
    2085     }
    2086   }
    2087 
    2088   mrb_name_error(mrb, mid, "method '%S' not defined in %S",
    2089     mrb_sym2str(mrb, mid), mod);
    2090 }
    2091 
    2092 /* 15.2.2.4.41 */
    2093 /*
    2094  *  call-seq:
    2095  *     remove_method(symbol)   -> self
    2096  *
    2097  *  Removes the method identified by _symbol_ from the current
    2098  *  class. For an example, see <code>Module.undef_method</code>.
    2099  */
    2100 
    2101 static mrb_value
    2102 mrb_mod_remove_method(mrb_state *mrb, mrb_value mod)
    2103 {
    2104   mrb_int argc;
    2105   mrb_value *argv;
    2106 
    2107   mrb_get_args(mrb, "*", &argv, &argc);
    2108   while (argc--) {
    2109     remove_method(mrb, mod, to_sym(mrb, *argv));
    2110     argv++;
    2111   }
    2112   return mod;
    2113 }
    2114 
    2115 
    2116 
    2117 static void
    2118 check_const_name_str(mrb_state *mrb, mrb_value str)
    2119 {
    2120   if (RSTRING_LEN(str) < 1 || !ISUPPER(*RSTRING_PTR(str))) {
    2121     mrb_name_error(mrb, mrb_intern_str(mrb, str), "wrong constant name %S", str);
    2122   }
    2123 }
    2124 
    2125 static void
    2126 check_const_name_sym(mrb_state *mrb, mrb_sym id)
    2127 {
    2128   check_const_name_str(mrb, mrb_sym2str(mrb, id));
    2129 }
    2130 
    2131 static mrb_value
    2132 const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool inherit)
    2133 {
    2134   if (inherit) {
    2135     return mrb_bool_value(mrb_const_defined(mrb, mod, id));
    2136   }
    2137   return mrb_bool_value(mrb_const_defined_at(mrb, mod, id));
    2138 }
    2139 
    2140 static mrb_value
    2141 mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
    2142 {
    2143   mrb_sym id;
    2144   mrb_bool inherit = TRUE;
    2145 
    2146   mrb_get_args(mrb, "n|b", &id, &inherit);
    2147   check_const_name_sym(mrb, id);
    2148   return const_defined(mrb, mod, id, inherit);
    2149 }
    2150 
    2151 static mrb_value
    2152 mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
    2153 {
    2154   mrb_sym id;
    2155 
    2156   mrb_get_args(mrb, "n", &id);
    2157   check_const_name_sym(mrb, id);
    2158   return mrb_const_get(mrb, mod, id);
    2159 }
    2160 
    2161 static mrb_value
    2162 mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
    2163 {
    2164   mrb_sym id;
    2165   mrb_value value;
    2166 
    2167   mrb_get_args(mrb, "no", &id, &value);
    2168   check_const_name_sym(mrb, id);
    2169   mrb_const_set(mrb, mod, id, value);
    2170   return value;
    2171 }
    2172 
    2173 static mrb_value
    2174 mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
    2175 {
    2176   mrb_sym id;
    2177   mrb_value val;
    2178 
    2179   mrb_get_args(mrb, "n", &id);
    2180   check_const_name_sym(mrb, id);
    2181   val = mrb_iv_remove(mrb, mod, id);
    2182   if (mrb_undef_p(val)) {
    2183     mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id));
    2184   }
    2185   return val;
    2186 }
    2187 
    2188 static mrb_value
    2189 mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
    2190 {
    2191   mrb_sym sym;
    2192 
    2193   mrb_get_args(mrb, "n", &sym);
    2194 
    2195   if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
    2196     mrb_name_error(mrb, sym, "uninitialized constant %S::%S",
    2197                    mod,
    2198                    mrb_sym2str(mrb, sym));
    2199   }
    2200   else {
    2201     mrb_name_error(mrb, sym, "uninitialized constant %S",
    2202                    mrb_sym2str(mrb, sym));
    2203   }
    2204   /* not reached */
    2205   return mrb_nil_value();
    2206 }
    2207 
    2208 static mrb_value
    2209 mrb_mod_s_constants(mrb_state *mrb, mrb_value mod)
    2210 {
    2211   mrb_raise(mrb, E_NOTIMP_ERROR, "Module.constants not implemented");
    2212   return mrb_nil_value();       /* not reached */
     2080static mrb_value
     2081mod_define_method(mrb_state *mrb, mrb_value self)
     2082{
     2083  struct RClass *c = mrb_class_ptr(self);
     2084  struct RProc *p;
     2085  mrb_method_t m;
     2086  mrb_sym mid;
     2087  mrb_value proc = mrb_undef_value();
     2088  mrb_value blk;
     2089
     2090  mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
     2091  switch (mrb_type(proc)) {
     2092    case MRB_TT_PROC:
     2093      blk = proc;
     2094      break;
     2095    case MRB_TT_UNDEF:
     2096      /* ignored */
     2097      break;
     2098    default:
     2099      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %T (expected Proc)", proc);
     2100      break;
     2101  }
     2102  if (mrb_nil_p(blk)) {
     2103    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
     2104  }
     2105  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
     2106  mrb_proc_copy(p, mrb_proc_ptr(blk));
     2107  p->flags |= MRB_PROC_STRICT;
     2108  MRB_METHOD_FROM_PROC(m, p);
     2109  mrb_define_method_raw(mrb, c, mid, m);
     2110  return mrb_symbol_value(mid);
     2111}
     2112
     2113static mrb_value
     2114top_define_method(mrb_state *mrb, mrb_value self)
     2115{
     2116  return mod_define_method(mrb, mrb_obj_value(mrb->object_class));
    22132117}
    22142118
     
    22252129}
    22262130
    2227 MRB_API mrb_value
     2131static mrb_value
     2132mrb_mod_dup(mrb_state *mrb, mrb_value self)
     2133{
     2134  mrb_value mod = mrb_obj_clone(mrb, self);
     2135  MRB_UNSET_FROZEN_FLAG(mrb_obj_ptr(mod));
     2136  return mod;
     2137}
     2138
     2139static mrb_value
    22282140mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
    22292141{
     
    22312143  mrb_int argc, i;
    22322144  mrb_sym mid;
    2233   struct RProc *method_rproc;
     2145  mrb_method_t m;
    22342146  struct RClass *rclass;
    22352147  int ai;
     
    22512163    mid = mrb_symbol(argv[i]);
    22522164    rclass = mrb_class_ptr(mod);
    2253     method_rproc = mrb_method_search(mrb, rclass, mid);
     2165    m = mrb_method_search(mrb, rclass, mid);
    22542166
    22552167    prepare_singleton_class(mrb, (struct RBasic*)rclass);
    22562168    ai = mrb_gc_arena_save(mrb);
    2257     mrb_define_method_raw(mrb, rclass->c, mid, method_rproc);
     2169    mrb_define_method_raw(mrb, rclass->c, mid, m);
    22582170    mrb_gc_arena_restore(mrb, ai);
    22592171  }
     
    22662178/* implementation of instance_eval */
    22672179mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value);
     2180
     2181static mrb_value
     2182inspect_main(mrb_state *mrb, mrb_value mod)
     2183{
     2184  return mrb_str_new_lit(mrb, "main");
     2185}
     2186
     2187static const mrb_code new_iseq[] = {
     2188  OP_ENTER, 0x0, 0x10, 0x1,  /* OP_ENTER     0:0:1:0:0:0:1 */
     2189  OP_LOADSELF, 0x3,          /* OP_LOADSELF  R3 */
     2190  OP_SEND, 0x3, 0x0, 0x0,    /* OP_SEND      R3  :allocate  0 */
     2191  OP_MOVE, 0x0, 0x3,         /* OP_MOVE      R0  R3 */
     2192  OP_MOVE, 0x4, 0x1,         /* OP_MOVE      R4  R1 */
     2193  OP_MOVE, 0x5, 0x2,         /* OP_MOVE      R5  R2 */
     2194  OP_SENDVB, 0x3, 0x1,       /* OP_SENDVB    R4  :initialize */
     2195  OP_RETURN, 0x0             /* OP_RETURN    R0 */
     2196};
     2197
     2198static void
     2199init_class_new(mrb_state *mrb, struct RClass *cls)
     2200{
     2201  struct RProc *p;
     2202  mrb_method_t m;
     2203  mrb_irep *new_irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep));
     2204  static const mrb_irep mrb_irep_zero = { 0 };
     2205
     2206  *new_irep = mrb_irep_zero;
     2207  new_irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*2);
     2208  new_irep->syms[0] = mrb_intern_lit(mrb, "allocate");
     2209  new_irep->syms[1] = mrb_intern_lit(mrb, "initialize");
     2210  new_irep->slen = 2;
     2211  new_irep->flags = MRB_ISEQ_NO_FREE;
     2212  new_irep->iseq = new_iseq;
     2213  new_irep->ilen = sizeof(new_iseq);
     2214  new_irep->nregs = 6;
     2215  new_irep->nlocals = 3;
     2216  p = mrb_proc_new(mrb, new_irep);
     2217  MRB_METHOD_FROM_PROC(m, p);
     2218  mrb_define_method_raw(mrb, cls, mrb_intern_lit(mrb, "new"), m);
     2219}
    22682220
    22692221void
     
    22892241  /* name basic classes */
    22902242  mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob));
    2291   mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob));
    22922243  mrb_define_const(mrb, obj, "Object",      mrb_obj_value(obj));
    22932244  mrb_define_const(mrb, obj, "Module",      mrb_obj_value(mod));
     
    22952246
    22962247  /* name each classes */
    2297   name_class(mrb, bob, mrb_intern_lit(mrb, "BasicObject"));
    2298   name_class(mrb, obj, mrb_intern_lit(mrb, "Object"));          /* 15.2.1 */
    2299   name_class(mrb, mod, mrb_intern_lit(mrb, "Module"));          /* 15.2.2 */
    2300   name_class(mrb, cls, mrb_intern_lit(mrb, "Class"));            /* 15.2.3 */
     2248  mrb_class_name_class(mrb, NULL, bob, mrb_intern_lit(mrb, "BasicObject"));
     2249  mrb_class_name_class(mrb, NULL, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */
     2250  mrb_class_name_class(mrb, NULL, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */
     2251  mrb_class_name_class(mrb, NULL, cls, mrb_intern_lit(mrb, "Class"));  /* 15.2.3 */
    23012252
    23022253  mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class);  /* 15.2.17 */
     
    23082259  mrb_define_method(mrb, bob, "==",                      mrb_obj_equal_m,          MRB_ARGS_REQ(1)); /* 15.3.1.3.1  */
    23092260  mrb_define_method(mrb, bob, "!=",                      mrb_obj_not_equal_m,      MRB_ARGS_REQ(1));
    2310   mrb_define_method(mrb, bob, "__id__",                  mrb_obj_id_m,             MRB_ARGS_NONE()); /* 15.3.1.3.3  */
    2311   mrb_define_method(mrb, bob, "__send__",                mrb_f_send,               MRB_ARGS_ANY());  /* 15.3.1.3.4  */
    2312   mrb_define_method(mrb, bob, "instance_eval",           mrb_obj_instance_eval,    MRB_ARGS_ANY());  /* 15.3.1.3.18 */
    2313 
    2314   mrb_define_class_method(mrb, cls, "new",               mrb_class_new_class,      MRB_ARGS_OPT(1));
     2261  mrb_define_method(mrb, bob, "__id__",                  mrb_obj_id_m,             MRB_ARGS_NONE()); /* 15.3.1.3.4  */
     2262  mrb_define_method(mrb, bob, "__send__",                mrb_f_send,               MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK());  /* 15.3.1.3.5  */
     2263  mrb_define_method(mrb, bob, "equal?",                  mrb_obj_equal_m,          MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */
     2264  mrb_define_method(mrb, bob, "instance_eval",           mrb_obj_instance_eval,    MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());  /* 15.3.1.3.18 */
     2265
     2266  mrb_define_class_method(mrb, cls, "new",               mrb_class_new_class,      MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());
     2267  mrb_define_method(mrb, cls, "allocate",                mrb_instance_alloc,       MRB_ARGS_NONE());
    23152268  mrb_define_method(mrb, cls, "superclass",              mrb_class_superclass,     MRB_ARGS_NONE()); /* 15.2.3.3.4 */
    2316   mrb_define_method(mrb, cls, "new",                     mrb_instance_new,         MRB_ARGS_ANY());  /* 15.2.3.3.3 */
    23172269  mrb_define_method(mrb, cls, "initialize",              mrb_class_initialize,     MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
    23182270  mrb_define_method(mrb, cls, "inherited",               mrb_bob_init,             MRB_ARGS_REQ(1));
    23192271
     2272  init_class_new(mrb, cls);
     2273
    23202274  MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
    2321   mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined,     MRB_ARGS_REQ(1)); /* 15.2.2.4.16 */
    2322   mrb_define_method(mrb, mod, "class_variable_get",      mrb_mod_cvar_get,         MRB_ARGS_REQ(1)); /* 15.2.2.4.17 */
    2323   mrb_define_method(mrb, mod, "class_variable_set",      mrb_mod_cvar_set,         MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */
    23242275  mrb_define_method(mrb, mod, "extend_object",           mrb_mod_extend_object,    MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
    23252276  mrb_define_method(mrb, mod, "extended",                mrb_bob_init,             MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
     
    23302281  mrb_define_method(mrb, mod, "class_eval",              mrb_mod_module_eval,      MRB_ARGS_ANY());  /* 15.2.2.4.15 */
    23312282  mrb_define_method(mrb, mod, "included",                mrb_bob_init,             MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
    2332   mrb_define_method(mrb, mod, "included_modules",        mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */
    23332283  mrb_define_method(mrb, mod, "initialize",              mrb_mod_initialize,       MRB_ARGS_NONE()); /* 15.2.2.4.31 */
    2334   mrb_define_method(mrb, mod, "instance_methods",        mrb_mod_instance_methods, MRB_ARGS_ANY());  /* 15.2.2.4.33 */
    2335   mrb_define_method(mrb, mod, "method_defined?",         mrb_mod_method_defined,   MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
    23362284  mrb_define_method(mrb, mod, "module_eval",             mrb_mod_module_eval,      MRB_ARGS_ANY());  /* 15.2.2.4.35 */
    23372285  mrb_define_method(mrb, mod, "module_function",         mrb_mod_module_function,  MRB_ARGS_ANY());
     
    23392287  mrb_define_method(mrb, mod, "protected",               mrb_mod_dummy_visibility, MRB_ARGS_ANY());  /* 15.2.2.4.37 */
    23402288  mrb_define_method(mrb, mod, "public",                  mrb_mod_dummy_visibility, MRB_ARGS_ANY());  /* 15.2.2.4.38 */
    2341   mrb_define_method(mrb, mod, "remove_class_variable",   mrb_mod_remove_cvar,      MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */
    2342   mrb_define_method(mrb, mod, "remove_method",           mrb_mod_remove_method,    MRB_ARGS_ANY());  /* 15.2.2.4.41 */
    2343   mrb_define_method(mrb, mod, "method_removed",          mrb_bob_init,             MRB_ARGS_REQ(1));
    23442289  mrb_define_method(mrb, mod, "attr_reader",             mrb_mod_attr_reader,      MRB_ARGS_ANY());  /* 15.2.2.4.13 */
    23452290  mrb_define_method(mrb, mod, "attr_writer",             mrb_mod_attr_writer,      MRB_ARGS_ANY());  /* 15.2.2.4.14 */
     
    23522297  mrb_define_method(mrb, mod, "const_get",               mrb_mod_const_get,        MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */
    23532298  mrb_define_method(mrb, mod, "const_set",               mrb_mod_const_set,        MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */
    2354   mrb_define_method(mrb, mod, "constants",               mrb_mod_constants,        MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */
    23552299  mrb_define_method(mrb, mod, "remove_const",            mrb_mod_remove_const,     MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */
    23562300  mrb_define_method(mrb, mod, "const_missing",           mrb_mod_const_missing,    MRB_ARGS_REQ(1));
     2301  mrb_define_method(mrb, mod, "method_defined?",         mrb_mod_method_defined,   MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
    23572302  mrb_define_method(mrb, mod, "define_method",           mod_define_method,        MRB_ARGS_ARG(1,1));
    2358   mrb_define_method(mrb, mod, "class_variables",         mrb_mod_class_variables,  MRB_ARGS_NONE()); /* 15.2.2.4.19 */
    2359   mrb_define_method(mrb, mod, "===",                     mrb_mod_eqq,              MRB_ARGS_REQ(1));
    2360   mrb_define_class_method(mrb, mod, "constants",         mrb_mod_s_constants,      MRB_ARGS_ANY());  /* 15.2.2.3.1 */
     2303  mrb_define_method(mrb, mod, "===",                     mrb_mod_eqq,              MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */
     2304  mrb_define_method(mrb, mod, "dup",                     mrb_mod_dup,              MRB_ARGS_NONE());
    23612305
    23622306  mrb_undef_method(mrb, cls, "append_features");
     2307  mrb_undef_method(mrb, cls, "prepend_features");
    23632308  mrb_undef_method(mrb, cls, "extend_object");
    2364 }
     2309  mrb_undef_method(mrb, cls, "module_function");
     2310
     2311  mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
     2312  mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
     2313  mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
     2314  mrb_define_singleton_method(mrb, mrb->top_self, "define_method", top_define_method, MRB_ARGS_ARG(1,1));
     2315}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/codedump.c

    r331 r439  
    77
    88#ifndef MRB_DISABLE_STDIO
    9 static int
    10 print_r(mrb_state *mrb, mrb_irep *irep, size_t n, int pre)
     9static void
     10print_r(mrb_state *mrb, mrb_irep *irep, size_t n)
    1111{
    1212  size_t i;
    1313
    14   if (n == 0) return 0;
     14  if (n == 0) return;
    1515
    1616  for (i=0; i+1<irep->nlocals; i++) {
    1717    if (irep->lv[i].r == n) {
    1818      mrb_sym sym = irep->lv[i].name;
    19       if (pre) printf(" ");
    20       printf("R%d:%s", (int)n, mrb_sym2name(mrb, sym));
    21       return 1;
     19      printf(" R%d:%s", (int)n, mrb_sym_dump(mrb, sym));
     20      break;
    2221    }
    2322  }
    24   return 0;
    25 }
    26 
    27 #define RA  1
    28 #define RB  2
    29 #define RAB 3
     23}
    3024
    3125static void
    32 print_lv(mrb_state *mrb, mrb_irep *irep, mrb_code c, int r)
    33 {
    34   int pre = 0;
    35 
    36   if (!irep->lv
    37       || ((!(r & RA) || GETARG_A(c) >= irep->nlocals)
    38        && (!(r & RB) || GETARG_B(c) >= irep->nlocals))) {
     26print_lv_a(mrb_state *mrb, mrb_irep *irep, uint16_t a)
     27{
     28  if (!irep->lv || a >= irep->nlocals || a == 0) {
    3929    printf("\n");
    4030    return;
    4131  }
    42   printf("\t; ");
    43   if (r & RA) {
    44     pre = print_r(mrb, irep, GETARG_A(c), 0);
    45   }
    46   if (r & RB) {
    47     print_r(mrb, irep, GETARG_B(c), pre);
    48   }
     32  printf("\t;");
     33  print_r(mrb, irep, a);
    4934  printf("\n");
    5035}
    51 #endif
     36
     37static void
     38print_lv_ab(mrb_state *mrb, mrb_irep *irep, uint16_t a, uint16_t b)
     39{
     40  if (!irep->lv || (a >= irep->nlocals && b >= irep->nlocals) || a+b == 0) {
     41    printf("\n");
     42    return;
     43  }
     44  printf("\t;");
     45  if (a > 0) print_r(mrb, irep, a);
     46  if (b > 0) print_r(mrb, irep, b);
     47  printf("\n");
     48}
     49
     50static void
     51print_header(mrb_state *mrb, mrb_irep *irep, ptrdiff_t i)
     52{
     53  int32_t line;
     54
     55  line = mrb_debug_get_line(mrb, irep, i);
     56  if (line < 0) {
     57    printf("      ");
     58  }
     59  else {
     60    printf("%5d ", line);
     61  }
     62
     63  printf("%03d ", (int)i);
     64}
     65
     66#define CASE(insn,ops) case insn: FETCH_ ## ops (); L_ ## insn
    5267
    5368static void
    5469codedump(mrb_state *mrb, mrb_irep *irep)
    5570{
    56 #ifndef MRB_DISABLE_STDIO
    57   int i;
    5871  int ai;
    59   mrb_code c;
     72  const mrb_code *pc, *pcend;
     73  mrb_code ins;
    6074  const char *file = NULL, *next_file;
    61   int32_t line;
    6275
    6376  if (!irep) return;
    64   printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", (void*)irep,
    65          irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen);
    66 
    67   for (i = 0; i < (int)irep->ilen; i++) {
     77  printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d iseq=%d\n", (void*)irep,
     78         irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen);
     79
     80  if (irep->lv) {
     81    int i;
     82
     83    printf("local variable names:\n");
     84    for (i = 1; i < irep->nlocals; ++i) {
     85      char const *s = mrb_sym_dump(mrb, irep->lv[i - 1].name);
     86      int n = irep->lv[i - 1].r ? irep->lv[i - 1].r : i;
     87      printf("  R%d:%s\n", n, s ? s : "");
     88    }
     89  }
     90
     91  pc = irep->iseq;
     92  pcend = pc + irep->ilen;
     93  while (pc < pcend) {
     94    ptrdiff_t i;
     95    uint32_t a;
     96    uint16_t b;
     97    uint8_t c;
     98
    6899    ai = mrb_gc_arena_save(mrb);
    69100
    70     next_file = mrb_debug_get_filename(irep, i);
     101    i = pc - irep->iseq;
     102    next_file = mrb_debug_get_filename(mrb, irep, i);
    71103    if (next_file && file != next_file) {
    72104      printf("file: %s\n", next_file);
    73105      file = next_file;
    74106    }
    75     line = mrb_debug_get_line(irep, i);
    76     if (line < 0) {
    77       printf("      ");
    78     }
    79     else {
    80       printf("%5d ", line);
    81     }
    82 
    83     printf("%03d ", i);
    84     c = irep->iseq[i];
    85     switch (GET_OPCODE(c)) {
    86     case OP_NOP:
     107    print_header(mrb, irep, i);
     108    ins = READ_B();
     109    switch (ins) {
     110    CASE(OP_NOP, Z):
    87111      printf("OP_NOP\n");
    88112      break;
    89     case OP_MOVE:
    90       printf("OP_MOVE\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
    91       print_lv(mrb, irep, c, RAB);
    92       break;
    93     case OP_LOADL:
     113    CASE(OP_MOVE, BB):
     114      printf("OP_MOVE\tR%d\tR%d\t", a, b);
     115      print_lv_ab(mrb, irep, a, b);
     116      break;
     117    CASE(OP_LOADL, BB):
    94118      {
    95         mrb_value v = irep->pool[GETARG_Bx(c)];
     119        mrb_value v = irep->pool[b];
    96120        mrb_value s = mrb_inspect(mrb, v);
    97         printf("OP_LOADL\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s));
     121        printf("OP_LOADL\tR%d\tL(%d)\t; %s", a, b, RSTRING_PTR(s));
    98122      }
    99       print_lv(mrb, irep, c, RA);
    100       break;
    101     case OP_LOADI:
    102       printf("OP_LOADI\tR%d\t%d\t", GETARG_A(c), GETARG_sBx(c));
    103       print_lv(mrb, irep, c, RA);
    104       break;
    105     case OP_LOADSYM:
    106       printf("OP_LOADSYM\tR%d\t:%s", GETARG_A(c),
    107              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
    108       print_lv(mrb, irep, c, RA);
    109       break;
    110     case OP_LOADNIL:
    111       printf("OP_LOADNIL\tR%d\t\t", GETARG_A(c));
    112       print_lv(mrb, irep, c, RA);
    113       break;
    114     case OP_LOADSELF:
    115       printf("OP_LOADSELF\tR%d\t\t", GETARG_A(c));
    116       print_lv(mrb, irep, c, RA);
    117       break;
    118     case OP_LOADT:
    119       printf("OP_LOADT\tR%d\t\t", GETARG_A(c));
    120       print_lv(mrb, irep, c, RA);
    121       break;
    122     case OP_LOADF:
    123       printf("OP_LOADF\tR%d\t\t", GETARG_A(c));
    124       print_lv(mrb, irep, c, RA);
    125       break;
    126     case OP_GETGLOBAL:
    127       printf("OP_GETGLOBAL\tR%d\t:%s", GETARG_A(c),
    128              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
    129       print_lv(mrb, irep, c, RA);
    130       break;
    131     case OP_SETGLOBAL:
    132       printf("OP_SETGLOBAL\t:%s\tR%d\t",
    133              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
    134              GETARG_A(c));
    135       print_lv(mrb, irep, c, RA);
    136       break;
    137     case OP_GETCONST:
    138       printf("OP_GETCONST\tR%d\t:%s", GETARG_A(c),
    139              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
    140       print_lv(mrb, irep, c, RA);
    141       break;
    142     case OP_SETCONST:
    143       printf("OP_SETCONST\t:%s\tR%d\t",
    144              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
    145              GETARG_A(c));
    146       print_lv(mrb, irep, c, RA);
    147       break;
    148     case OP_GETMCNST:
    149       printf("OP_GETMCNST\tR%d\tR%d::%s", GETARG_A(c), GETARG_A(c),
    150              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
    151       print_lv(mrb, irep, c, RAB);
    152       break;
    153     case OP_SETMCNST:
    154       printf("OP_SETMCNST\tR%d::%s\tR%d", GETARG_A(c)+1,
    155              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
    156              GETARG_A(c));
    157       print_lv(mrb, irep, c, RA);
    158       break;
    159     case OP_GETIV:
    160       printf("OP_GETIV\tR%d\t%s", GETARG_A(c),
    161              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
    162       print_lv(mrb, irep, c, RA);
    163       break;
    164     case OP_SETIV:
    165       printf("OP_SETIV\t%s\tR%d",
    166              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
    167              GETARG_A(c));
    168       print_lv(mrb, irep, c, RA);
    169       break;
    170     case OP_GETUPVAR:
    171       printf("OP_GETUPVAR\tR%d\t%d\t%d",
    172              GETARG_A(c), GETARG_B(c), GETARG_C(c));
    173       print_lv(mrb, irep, c, RA);
    174       break;
    175     case OP_SETUPVAR:
    176       printf("OP_SETUPVAR\tR%d\t%d\t%d",
    177              GETARG_A(c), GETARG_B(c), GETARG_C(c));
    178       print_lv(mrb, irep, c, RA);
    179       break;
    180     case OP_GETCV:
    181       printf("OP_GETCV\tR%d\t%s", GETARG_A(c),
    182              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
    183       print_lv(mrb, irep, c, RA);
    184       break;
    185     case OP_SETCV:
    186       printf("OP_SETCV\t%s\tR%d",
    187              mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
    188              GETARG_A(c));
    189       print_lv(mrb, irep, c, RA);
    190       break;
    191     case OP_JMP:
    192       printf("OP_JMP\t%03d\n", i+GETARG_sBx(c));
    193       break;
    194     case OP_JMPIF:
    195       printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
    196       break;
    197     case OP_JMPNOT:
    198       printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
    199       break;
    200     case OP_SEND:
    201       printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c),
    202              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    203              GETARG_C(c));
    204       break;
    205     case OP_SENDB:
    206       printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c),
    207              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    208              GETARG_C(c));
    209       break;
    210     case OP_TAILCALL:
    211       printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c),
    212              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    213              GETARG_C(c));
    214       break;
    215     case OP_SUPER:
    216       printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c),
    217              GETARG_C(c));
    218       break;
    219     case OP_ARGARY:
    220       printf("OP_ARGARY\tR%d\t%d:%d:%d:%d", GETARG_A(c),
    221              (GETARG_Bx(c)>>10)&0x3f,
    222              (GETARG_Bx(c)>>9)&0x1,
    223              (GETARG_Bx(c)>>4)&0x1f,
    224              (GETARG_Bx(c)>>0)&0xf);
    225       print_lv(mrb, irep, c, RA);
    226       break;
    227 
    228     case OP_ENTER:
     123      print_lv_a(mrb, irep, a);
     124      break;
     125    CASE(OP_LOADI, BB):
     126      printf("OP_LOADI\tR%d\t%d\t", a, b);
     127      print_lv_a(mrb, irep, a);
     128      break;
     129    CASE(OP_LOADINEG, BB):
     130      printf("OP_LOADI\tR%d\t-%d\t", a, b);
     131      print_lv_a(mrb, irep, a);
     132      break;
     133    CASE(OP_LOADI__1, B):
     134      printf("OP_LOADI__1\tR%d\t\t", a);
     135      print_lv_a(mrb, irep, a);
     136      break;
     137    CASE(OP_LOADI_0, B): goto L_LOADI;
     138    CASE(OP_LOADI_1, B): goto L_LOADI;
     139    CASE(OP_LOADI_2, B): goto L_LOADI;
     140    CASE(OP_LOADI_3, B): goto L_LOADI;
     141    CASE(OP_LOADI_4, B): goto L_LOADI;
     142    CASE(OP_LOADI_5, B): goto L_LOADI;
     143    CASE(OP_LOADI_6, B): goto L_LOADI;
     144    CASE(OP_LOADI_7, B):
     145    L_LOADI:
     146      printf("OP_LOADI_%d\tR%d\t\t", ins-(int)OP_LOADI_0, a);
     147      print_lv_a(mrb, irep, a);
     148      break;
     149    CASE(OP_LOADSYM, BB):
     150      printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
     151      print_lv_a(mrb, irep, a);
     152      break;
     153    CASE(OP_LOADNIL, B):
     154      printf("OP_LOADNIL\tR%d\t\t", a);
     155      print_lv_a(mrb, irep, a);
     156      break;
     157    CASE(OP_LOADSELF, B):
     158      printf("OP_LOADSELF\tR%d\t\t", a);
     159      print_lv_a(mrb, irep, a);
     160      break;
     161    CASE(OP_LOADT, B):
     162      printf("OP_LOADT\tR%d\t\t", a);
     163      print_lv_a(mrb, irep, a);
     164      break;
     165    CASE(OP_LOADF, B):
     166      printf("OP_LOADF\tR%d\t\t", a);
     167      print_lv_a(mrb, irep, a);
     168      break;
     169    CASE(OP_GETGV, BB):
     170      printf("OP_GETGV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
     171      print_lv_a(mrb, irep, a);
     172      break;
     173    CASE(OP_SETGV, BB):
     174      printf("OP_SETGV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
     175      print_lv_a(mrb, irep, a);
     176      break;
     177    CASE(OP_GETSV, BB):
     178      printf("OP_GETSV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
     179      print_lv_a(mrb, irep, a);
     180      break;
     181    CASE(OP_SETSV, BB):
     182      printf("OP_SETSV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
     183      print_lv_a(mrb, irep, a);
     184      break;
     185    CASE(OP_GETCONST, BB):
     186      printf("OP_GETCONST\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
     187      print_lv_a(mrb, irep, a);
     188      break;
     189    CASE(OP_SETCONST, BB):
     190      printf("OP_SETCONST\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
     191      print_lv_a(mrb, irep, a);
     192      break;
     193    CASE(OP_GETMCNST, BB):
     194      printf("OP_GETMCNST\tR%d\tR%d::%s", a, a, mrb_sym_dump(mrb, irep->syms[b]));
     195      print_lv_a(mrb, irep, a);
     196      break;
     197    CASE(OP_SETMCNST, BB):
     198      printf("OP_SETMCNST\tR%d::%s\tR%d", a+1, mrb_sym_dump(mrb, irep->syms[b]), a);
     199      print_lv_a(mrb, irep, a);
     200      break;
     201    CASE(OP_GETIV, BB):
     202      printf("OP_GETIV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
     203      print_lv_a(mrb, irep, a);
     204      break;
     205    CASE(OP_SETIV, BB):
     206      printf("OP_SETIV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
     207      print_lv_a(mrb, irep, a);
     208      break;
     209    CASE(OP_GETUPVAR, BBB):
     210      printf("OP_GETUPVAR\tR%d\t%d\t%d", a, b, c);
     211      print_lv_a(mrb, irep, a);
     212      break;
     213    CASE(OP_SETUPVAR, BBB):
     214      printf("OP_SETUPVAR\tR%d\t%d\t%d", a, b, c);
     215      print_lv_a(mrb, irep, a);
     216      break;
     217    CASE(OP_GETCV, BB):
     218      printf("OP_GETCV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
     219      print_lv_a(mrb, irep, a);
     220      break;
     221    CASE(OP_SETCV, BB):
     222      printf("OP_SETCV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
     223      print_lv_a(mrb, irep, a);
     224      break;
     225    CASE(OP_JMP, S):
     226      printf("OP_JMP\t\t%03d\n", a);
     227      break;
     228    CASE(OP_JMPIF, BS):
     229      printf("OP_JMPIF\tR%d\t%03d\t", a, b);
     230      print_lv_a(mrb, irep, a);
     231      break;
     232    CASE(OP_JMPNOT, BS):
     233      printf("OP_JMPNOT\tR%d\t%03d\t", a, b);
     234      print_lv_a(mrb, irep, a);
     235      break;
     236    CASE(OP_JMPNIL, BS):
     237      printf("OP_JMPNIL\tR%d\t%03d\t", a, b);
     238      print_lv_a(mrb, irep, a);
     239      break;
     240    CASE(OP_SENDV, BB):
     241      printf("OP_SENDV\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
     242      break;
     243    CASE(OP_SENDVB, BB):
     244      printf("OP_SENDVB\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
     245      break;
     246    CASE(OP_SEND, BBB):
     247      printf("OP_SEND\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
     248      break;
     249    CASE(OP_SENDB, BBB):
     250      printf("OP_SENDB\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
     251      break;
     252    CASE(OP_CALL, Z):
     253      printf("OP_CALL\n");
     254      break;
     255    CASE(OP_SUPER, BB):
     256      printf("OP_SUPER\tR%d\t%d\n", a, b);
     257      break;
     258    CASE(OP_ARGARY, BS):
     259      printf("OP_ARGARY\tR%d\t%d:%d:%d:%d (%d)", a,
     260             (b>>11)&0x3f,
     261             (b>>10)&0x1,
     262             (b>>5)&0x1f,
     263             (b>>4)&0x1,
     264             (b>>0)&0xf);
     265      print_lv_a(mrb, irep, a);
     266      break;
     267    CASE(OP_ENTER, W):
    229268      printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
    230              (GETARG_Ax(c)>>18)&0x1f,
    231              (GETARG_Ax(c)>>13)&0x1f,
    232              (GETARG_Ax(c)>>12)&0x1,
    233              (GETARG_Ax(c)>>7)&0x1f,
    234              (GETARG_Ax(c)>>2)&0x1f,
    235              (GETARG_Ax(c)>>1)&0x1,
    236              GETARG_Ax(c) & 0x1);
    237       break;
    238     case OP_RETURN:
    239       printf("OP_RETURN\tR%d", GETARG_A(c));
    240       switch (GETARG_B(c)) {
    241       case OP_R_NORMAL:
    242         printf("\tnormal\t"); break;
    243       case OP_R_RETURN:
    244         printf("\treturn\t"); break;
    245       case OP_R_BREAK:
    246         printf("\tbreak\t"); break;
    247       default:
    248         printf("\tbroken\t"); break;
     269             MRB_ASPEC_REQ(a),
     270             MRB_ASPEC_OPT(a),
     271             MRB_ASPEC_REST(a),
     272             MRB_ASPEC_POST(a),
     273             MRB_ASPEC_KEY(a),
     274             MRB_ASPEC_KDICT(a),
     275             MRB_ASPEC_BLOCK(a));
     276      break;
     277    CASE(OP_KEY_P, BB):
     278      printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
     279      print_lv_a(mrb, irep, a);
     280      break;
     281    CASE(OP_KEYEND, Z):
     282      printf("OP_KEYEND\n");
     283      break;
     284    CASE(OP_KARG, BB):
     285      printf("OP_KARG\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
     286      print_lv_a(mrb, irep, a);
     287      break;
     288    CASE(OP_RETURN, B):
     289      printf("OP_RETURN\tR%d\t\t", a);
     290      print_lv_a(mrb, irep, a);
     291      break;
     292    CASE(OP_RETURN_BLK, B):
     293      printf("OP_RETURN_BLK\tR%d\t\t", a);
     294      print_lv_a(mrb, irep, a);
     295      break;
     296    CASE(OP_BREAK, B):
     297      printf("OP_BREAK\tR%d\t\t", a);
     298      print_lv_a(mrb, irep, a);
     299      break;
     300    CASE(OP_BLKPUSH, BS):
     301      printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d (%d)", a,
     302             (b>>11)&0x3f,
     303             (b>>10)&0x1,
     304             (b>>5)&0x1f,
     305             (b>>4)&0x1,
     306             (b>>0)&0xf);
     307      print_lv_a(mrb, irep, a);
     308      break;
     309    CASE(OP_LAMBDA, BB):
     310      printf("OP_LAMBDA\tR%d\tI(%d:%p)\n", a, b, irep->reps[b]);
     311      break;
     312    CASE(OP_BLOCK, BB):
     313      printf("OP_BLOCK\tR%d\tI(%d:%p)\n", a, b, irep->reps[b]);
     314      break;
     315    CASE(OP_METHOD, BB):
     316      printf("OP_METHOD\tR%d\tI(%d:%p)\n", a, b, irep->reps[b]);
     317      break;
     318    CASE(OP_RANGE_INC, B):
     319      printf("OP_RANGE_INC\tR%d\n", a);
     320      break;
     321    CASE(OP_RANGE_EXC, B):
     322      printf("OP_RANGE_EXC\tR%d\n", a);
     323      break;
     324    CASE(OP_DEF, BB):
     325      printf("OP_DEF\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
     326      break;
     327    CASE(OP_UNDEF, B):
     328      printf("OP_UNDEF\t:%s\n", mrb_sym_dump(mrb, irep->syms[a]));
     329      break;
     330    CASE(OP_ALIAS, BB):
     331      printf("OP_ALIAS\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b]));
     332      break;
     333    CASE(OP_ADD, B):
     334      printf("OP_ADD\tR%d\t\n", a);
     335      break;
     336    CASE(OP_ADDI, BB):
     337      printf("OP_ADDI\tR%d\t%d\n", a, b);
     338      break;
     339    CASE(OP_SUB, B):
     340      printf("OP_SUB\tR%d\t\n", a);
     341      break;
     342    CASE(OP_SUBI, BB):
     343      printf("OP_SUBI\tR%d\t%d\n", a, b);
     344      break;
     345    CASE(OP_MUL, B):
     346      printf("OP_MUL\tR%d\t\n", a);
     347      break;
     348    CASE(OP_DIV, B):
     349      printf("OP_DIV\tR%d\t\n", a);
     350      break;
     351    CASE(OP_LT, B):
     352      printf("OP_LT\t\tR%d\t\n", a);
     353      break;
     354    CASE(OP_LE, B):
     355      printf("OP_LE\t\tR%d\t\n", a);
     356      break;
     357    CASE(OP_GT, B):
     358      printf("OP_GT\t\tR%d\t\n", a);
     359      break;
     360    CASE(OP_GE, B):
     361      printf("OP_GE\t\tR%d\t\n", a);
     362      break;
     363    CASE(OP_EQ, B):
     364      printf("OP_EQ\t\tR%d\t\n", a);
     365      break;
     366    CASE(OP_ARRAY, BB):
     367      printf("OP_ARRAY\tR%d\t%d\t", a, b);
     368      print_lv_a(mrb, irep, a);
     369      break;
     370    CASE(OP_ARRAY2, BBB):
     371      printf("OP_ARRAY\tR%d\tR%d\t%d\t", a, b, c);
     372      print_lv_ab(mrb, irep, a, b);
     373      break;
     374    CASE(OP_ARYCAT, B):
     375      printf("OP_ARYCAT\tR%d\t", a);
     376      print_lv_a(mrb, irep, a);
     377      break;
     378    CASE(OP_ARYPUSH, B):
     379      printf("OP_ARYPUSH\tR%d\t", a);
     380      print_lv_a(mrb, irep, a);
     381      break;
     382    CASE(OP_ARYDUP, B):
     383      printf("OP_ARYDUP\tR%d\t", a);
     384      print_lv_a(mrb, irep, a);
     385      break;
     386    CASE(OP_AREF, BBB):
     387      printf("OP_AREF\tR%d\tR%d\t%d", a, b, c);
     388      print_lv_ab(mrb, irep, a, b);
     389      break;
     390    CASE(OP_ASET, BBB):
     391      printf("OP_ASET\tR%d\tR%d\t%d", a, b, c);
     392      print_lv_ab(mrb, irep, a, b);
     393      break;
     394    CASE(OP_APOST, BBB):
     395      printf("OP_APOST\tR%d\t%d\t%d", a, b, c);
     396      print_lv_a(mrb, irep, a);
     397      break;
     398    CASE(OP_INTERN, B):
     399      printf("OP_INTERN\tR%d", a);
     400      print_lv_a(mrb, irep, a);
     401      break;
     402    CASE(OP_STRING, BB):
     403      {
     404        mrb_value v = irep->pool[b];
     405        mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
     406        printf("OP_STRING\tR%d\tL(%d)\t; %s", a, b, RSTRING_PTR(s));
    249407      }
    250       print_lv(mrb, irep, c, RA);
    251       break;
    252     case OP_BLKPUSH:
    253       printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d", GETARG_A(c),
    254              (GETARG_Bx(c)>>10)&0x3f,
    255              (GETARG_Bx(c)>>9)&0x1,
    256              (GETARG_Bx(c)>>4)&0x1f,
    257              (GETARG_Bx(c)>>0)&0xf);
    258       print_lv(mrb, irep, c, RA);
    259       break;
    260 
    261     case OP_LAMBDA:
    262       printf("OP_LAMBDA\tR%d\tI(%+d)\t", GETARG_A(c), GETARG_b(c)+1);
    263       switch (GETARG_c(c)) {
    264       case OP_L_METHOD:
    265         printf("method"); break;
    266       case OP_L_BLOCK:
    267         printf("block"); break;
    268       case OP_L_LAMBDA:
    269         printf("lambda"); break;
    270       }
    271       print_lv(mrb, irep, c, RA);
    272       break;
    273     case OP_RANGE:
    274       printf("OP_RANGE\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
    275       print_lv(mrb, irep, c, RAB);
    276       break;
    277     case OP_METHOD:
    278       printf("OP_METHOD\tR%d\t:%s", GETARG_A(c),
    279              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
    280       print_lv(mrb, irep, c, RA);
    281       break;
    282 
    283     case OP_ADD:
    284       printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c),
    285              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    286              GETARG_C(c));
    287       break;
    288     case OP_ADDI:
    289       printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c),
    290              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    291              GETARG_C(c));
    292       break;
    293     case OP_SUB:
    294       printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c),
    295              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    296              GETARG_C(c));
    297       break;
    298     case OP_SUBI:
    299       printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c),
    300              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    301              GETARG_C(c));
    302       break;
    303     case OP_MUL:
    304       printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c),
    305              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    306              GETARG_C(c));
    307       break;
    308     case OP_DIV:
    309       printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c),
    310              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    311              GETARG_C(c));
    312       break;
    313     case OP_LT:
    314       printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c),
    315              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    316              GETARG_C(c));
    317       break;
    318     case OP_LE:
    319       printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c),
    320              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    321              GETARG_C(c));
    322       break;
    323     case OP_GT:
    324       printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c),
    325              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    326              GETARG_C(c));
    327       break;
    328     case OP_GE:
    329       printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c),
    330              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    331              GETARG_C(c));
    332       break;
    333     case OP_EQ:
    334       printf("OP_EQ\t\tR%d\t:%s\t%d\n", GETARG_A(c),
    335              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
    336              GETARG_C(c));
    337       break;
    338 
    339     case OP_STOP:
    340       printf("OP_STOP\n");
    341       break;
    342 
    343     case OP_ARRAY:
    344       printf("OP_ARRAY\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
    345       print_lv(mrb, irep, c, RAB);
    346       break;
    347     case OP_ARYCAT:
    348       printf("OP_ARYCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
    349       print_lv(mrb, irep, c, RAB);
    350       break;
    351     case OP_ARYPUSH:
    352       printf("OP_ARYPUSH\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
    353       print_lv(mrb, irep, c, RAB);
    354       break;
    355     case OP_AREF:
    356       printf("OP_AREF\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
    357       print_lv(mrb, irep, c, RAB);
    358       break;
    359     case OP_APOST:
    360       printf("OP_APOST\tR%d\t%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
    361       print_lv(mrb, irep, c, RA);
    362       break;
    363     case OP_STRING:
     408      print_lv_a(mrb, irep, a);
     409      break;
     410    CASE(OP_STRCAT, B):
     411      printf("OP_STRCAT\tR%d\t", a);
     412      print_lv_a(mrb, irep, a);
     413      break;
     414    CASE(OP_HASH, BB):
     415      printf("OP_HASH\tR%d\t%d\t", a, b);
     416      print_lv_a(mrb, irep, a);
     417      break;
     418    CASE(OP_HASHADD, BB):
     419      printf("OP_HASHADD\tR%d\t%d\t", a, b);
     420      print_lv_a(mrb, irep, a);
     421      break;
     422    CASE(OP_HASHCAT, B):
     423      printf("OP_HASHCAT\tR%d\t", a);
     424      print_lv_a(mrb, irep, a);
     425      break;
     426
     427    CASE(OP_OCLASS, B):
     428      printf("OP_OCLASS\tR%d\t\t", a);
     429      print_lv_a(mrb, irep, a);
     430      break;
     431    CASE(OP_CLASS, BB):
     432      printf("OP_CLASS\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
     433      print_lv_a(mrb, irep, a);
     434      break;
     435    CASE(OP_MODULE, BB):
     436      printf("OP_MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
     437      print_lv_a(mrb, irep, a);
     438      break;
     439    CASE(OP_EXEC, BB):
     440      printf("OP_EXEC\tR%d\tI(%d:%p)", a, b, irep->reps[b]);
     441      print_lv_a(mrb, irep, a);
     442      break;
     443    CASE(OP_SCLASS, B):
     444      printf("OP_SCLASS\tR%d\t", a);
     445      print_lv_a(mrb, irep, a);
     446      break;
     447    CASE(OP_TCLASS, B):
     448      printf("OP_TCLASS\tR%d\t\t", a);
     449      print_lv_a(mrb, irep, a);
     450      break;
     451    CASE(OP_ERR, B):
    364452      {
    365         mrb_value v = irep->pool[GETARG_Bx(c)];
    366         mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
    367         printf("OP_STRING\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s));
    368       }
    369       print_lv(mrb, irep, c, RA);
    370       break;
    371     case OP_STRCAT:
    372       printf("OP_STRCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
    373       print_lv(mrb, irep, c, RAB);
    374       break;
    375     case OP_HASH:
    376       printf("OP_HASH\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
    377       print_lv(mrb, irep, c, RAB);
    378       break;
    379 
    380     case OP_OCLASS:
    381       printf("OP_OCLASS\tR%d\t\t", GETARG_A(c));
    382       print_lv(mrb, irep, c, RA);
    383       break;
    384     case OP_CLASS:
    385       printf("OP_CLASS\tR%d\t:%s", GETARG_A(c),
    386              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
    387       print_lv(mrb, irep, c, RA);
    388       break;
    389     case OP_MODULE:
    390       printf("OP_MODULE\tR%d\t:%s", GETARG_A(c),
    391              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
    392       print_lv(mrb, irep, c, RA);
    393       break;
    394     case OP_EXEC:
    395       printf("OP_EXEC\tR%d\tI(%+d)", GETARG_A(c), GETARG_Bx(c)+1);
    396       print_lv(mrb, irep, c, RA);
    397       break;
    398     case OP_SCLASS:
    399       printf("OP_SCLASS\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
    400       print_lv(mrb, irep, c, RAB);
    401       break;
    402     case OP_TCLASS:
    403       printf("OP_TCLASS\tR%d\t\t", GETARG_A(c));
    404       print_lv(mrb, irep, c, RA);
    405       break;
    406     case OP_ERR:
    407       {
    408         mrb_value v = irep->pool[GETARG_Bx(c)];
     453        mrb_value v = irep->pool[a];
    409454        mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
    410455        printf("OP_ERR\t%s\n", RSTRING_PTR(s));
    411456      }
    412457      break;
    413     case OP_EPUSH:
    414       printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)+1);
    415       break;
    416     case OP_ONERR:
    417       printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c));
    418       break;
    419     case OP_RESCUE:
    420       {
    421         int a = GETARG_A(c);
    422         int b = GETARG_B(c);
    423         int cnt = GETARG_C(c);
    424 
    425         if (b == 0) {
    426           printf("OP_RESCUE\tR%d\t\t%s", a, cnt ? "cont" : "");
    427           print_lv(mrb, irep, c, RA);
    428           break;
    429         }
    430         else {
    431           printf("OP_RESCUE\tR%d\tR%d\t%s", a, b, cnt ? "cont" : "");
    432           print_lv(mrb, irep, c, RAB);
    433           break;
    434         }
     458    CASE(OP_EPUSH, B):
     459      printf("OP_EPUSH\t\t:I(%d:%p)\n", a, irep->reps[a]);
     460      break;
     461    CASE(OP_ONERR, S):
     462      printf("OP_ONERR\t%03d\n", a);
     463      break;
     464    CASE(OP_EXCEPT, B):
     465      printf("OP_EXCEPT\tR%d\t\t", a);
     466      print_lv_a(mrb, irep, a);
     467      break;
     468    CASE(OP_RESCUE, BB):
     469      printf("OP_RESCUE\tR%d\tR%d", a, b);
     470      print_lv_ab(mrb, irep, a, b);
     471      break;
     472    CASE(OP_RAISE, B):
     473      printf("OP_RAISE\tR%d\t\t", a);
     474      print_lv_a(mrb, irep, a);
     475      break;
     476    CASE(OP_POPERR, B):
     477      printf("OP_POPERR\t%d\t\t\n", a);
     478      break;
     479    CASE(OP_EPOP, B):
     480      printf("OP_EPOP\t%d\n", a);
     481      break;
     482
     483    CASE(OP_DEBUG, BBB):
     484      printf("OP_DEBUG\t%d\t%d\t%d\n", a, b, c);
     485      break;
     486
     487    CASE(OP_STOP, Z):
     488      printf("OP_STOP\n");
     489      break;
     490
     491    CASE(OP_EXT1, Z):
     492      ins = READ_B();
     493      printf("OP_EXT1\n");
     494      print_header(mrb, irep, pc-irep->iseq-2);
     495      switch (ins) {
     496#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); goto L_OP_ ## i;
     497#include "mruby/ops.h"
     498#undef OPCODE
    435499      }
    436500      break;
    437     case OP_RAISE:
    438       printf("OP_RAISE\tR%d\t\t", GETARG_A(c));
    439       print_lv(mrb, irep, c, RA);
    440       break;
    441     case OP_POPERR:
    442       printf("OP_POPERR\t%d\t\t\n", GETARG_A(c));
    443       break;
    444     case OP_EPOP:
    445       printf("OP_EPOP\t%d\n", GETARG_A(c));
     501    CASE(OP_EXT2, Z):
     502      ins = READ_B();
     503      printf("OP_EXT2\n");
     504      print_header(mrb, irep, pc-irep->iseq-2);
     505      switch (ins) {
     506#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); goto L_OP_ ## i;
     507#include "mruby/ops.h"
     508#undef OPCODE
     509      }
     510      break;
     511    CASE(OP_EXT3, Z):
     512      ins = READ_B();
     513      printf("OP_EXT3\n");
     514      print_header(mrb, irep, pc-irep->iseq-2);
     515      switch (ins) {
     516#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); goto L_OP_ ## i;
     517#include "mruby/ops.h"
     518#undef OPCODE
     519      }
    446520      break;
    447521
    448522    default:
    449       printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c),
    450              GETARG_A(c), GETARG_B(c), GETARG_C(c));
     523      printf("OP_unknown (0x%x)\n", ins);
    451524      break;
    452525    }
     
    454527  }
    455528  printf("\n");
    456 #endif
    457529}
    458530
     
    460532codedump_recur(mrb_state *mrb, mrb_irep *irep)
    461533{
    462   size_t i;
     534  int i;
    463535
    464536  codedump(mrb, irep);
     
    467539  }
    468540}
     541#endif
    469542
    470543void
    471544mrb_codedump_all(mrb_state *mrb, struct RProc *proc)
    472545{
     546#ifndef MRB_DISABLE_STDIO
    473547  codedump_recur(mrb, proc->body.irep);
    474 }
     548#endif
     549}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/debug.c

    r331 r439  
    44#include <mruby/debug.h>
    55
    6 static mrb_irep_debug_info_file *
     6static mrb_irep_debug_info_file*
    77get_file(mrb_irep_debug_info *info, uint32_t pc)
    88{
     
    5252
    5353MRB_API char const*
    54 mrb_debug_get_filename(mrb_irep *irep, uint32_t pc)
    55 {
    56   if (irep && pc < irep->ilen) {
     54mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc)
     55{
     56  if (irep && pc >= 0 && pc < irep->ilen) {
    5757    mrb_irep_debug_info_file* f = NULL;
    58     if (!irep->debug_info) { return irep->filename; }
    59     else if ((f = get_file(irep->debug_info, pc))) {
    60       return f->filename;
     58    if (!irep->debug_info) return NULL;
     59    else if ((f = get_file(irep->debug_info, (uint32_t)pc))) {
     60      return mrb_sym_name_len(mrb, f->filename_sym, NULL);
    6161    }
    6262  }
     
    6565
    6666MRB_API int32_t
    67 mrb_debug_get_line(mrb_irep *irep, uint32_t pc)
    68 {
    69   if (irep && pc < irep->ilen) {
     67mrb_debug_get_line(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc)
     68{
     69  if (irep && pc >= 0 && pc < irep->ilen) {
    7070    mrb_irep_debug_info_file* f = NULL;
    7171    if (!irep->debug_info) {
    72       return irep->lines? irep->lines[pc] : -1;
    73     }
    74     else if ((f = get_file(irep->debug_info, pc))) {
     72      return -1;
     73    }
     74    else if ((f = get_file(irep->debug_info, (uint32_t)pc))) {
    7575      switch (f->line_type) {
    7676        case mrb_debug_line_ary:
     
    109109}
    110110
    111 MRB_API mrb_irep_debug_info *
     111MRB_API mrb_irep_debug_info*
    112112mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep)
    113113{
     
    122122}
    123123
    124 MRB_API mrb_irep_debug_info_file *
    125 mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep,
     124MRB_API mrb_irep_debug_info_file*
     125mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d,
     126                           const char *filename, uint16_t *lines,
    126127                           uint32_t start_pos, uint32_t end_pos)
    127128{
    128   mrb_irep_debug_info *info;
    129   mrb_irep_debug_info_file *ret;
     129  mrb_irep_debug_info_file *f;
    130130  uint32_t file_pc_count;
    131131  size_t fn_len;
    132   mrb_int len;
    133132  uint32_t i;
    134133
    135   if (!irep->debug_info) { return NULL; }
    136 
    137   mrb_assert(irep->filename);
    138   mrb_assert(irep->lines);
    139 
    140   info = irep->debug_info;
    141 
    142   if (info->flen > 0 && strcmp(irep->filename, info->files[info->flen - 1]->filename) == 0) {
    143     return NULL;
    144   }
    145 
    146   ret = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*ret));
    147   info->files =
    148       (mrb_irep_debug_info_file**)(
    149           info->files
    150           ? mrb_realloc(mrb, info->files, sizeof(mrb_irep_debug_info_file*) * (info->flen + 1))
     134  if (!d) return NULL;
     135  if (start_pos == end_pos) return NULL;
     136
     137  mrb_assert(filename);
     138  mrb_assert(lines);
     139
     140  if (d->flen > 0) {
     141    const char *fn = mrb_sym_name_len(mrb, d->files[d->flen - 1]->filename_sym, NULL);
     142    if (strcmp(filename, fn) == 0)
     143      return NULL;
     144  }
     145
     146  f = (mrb_irep_debug_info_file*)mrb_malloc(mrb, sizeof(*f));
     147  d->files = (mrb_irep_debug_info_file**)(
     148          d->files
     149          ? mrb_realloc(mrb, d->files, sizeof(mrb_irep_debug_info_file*) * (d->flen + 1))
    151150          : mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file*)));
    152   info->files[info->flen++] = ret;
     151  d->files[d->flen++] = f;
    153152
    154153  file_pc_count = end_pos - start_pos;
    155154
    156   ret->start_pos = start_pos;
    157   info->pc_count = end_pos;
    158 
    159   fn_len = strlen(irep->filename);
    160   ret->filename_sym = mrb_intern(mrb, irep->filename, fn_len);
    161   len = 0;
    162   ret->filename = mrb_sym2name_len(mrb, ret->filename_sym, &len);
    163 
    164   ret->line_type = select_line_type(irep->lines + start_pos, end_pos - start_pos);
    165   ret->lines.ptr = NULL;
    166 
    167   switch (ret->line_type) {
     155  f->start_pos = start_pos;
     156  d->pc_count = end_pos;
     157
     158  fn_len = strlen(filename);
     159  f->filename_sym = mrb_intern(mrb, filename, fn_len);
     160
     161  f->line_type = select_line_type(lines + start_pos, end_pos - start_pos);
     162  f->lines.ptr = NULL;
     163
     164  switch (f->line_type) {
    168165    case mrb_debug_line_ary:
    169       ret->line_entry_count = file_pc_count;
    170       ret->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count);
     166      f->line_entry_count = file_pc_count;
     167      f->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count);
    171168      for (i = 0; i < file_pc_count; ++i) {
    172         ret->lines.ary[i] = irep->lines[start_pos + i];
     169        f->lines.ary[i] = lines[start_pos + i];
    173170      }
    174171      break;
     
    177174      uint16_t prev_line = 0;
    178175      mrb_irep_debug_info_line m;
    179       ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1);
    180       ret->line_entry_count = 0;
     176      f->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1);
     177      f->line_entry_count = 0;
    181178      for (i = 0; i < file_pc_count; ++i) {
    182         if (irep->lines[start_pos + i] == prev_line) { continue; }
    183 
    184         ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc(
    185             mrb, ret->lines.flat_map,
    186             sizeof(mrb_irep_debug_info_line) * (ret->line_entry_count + 1));
     179        if (lines[start_pos + i] == prev_line) { continue; }
     180
     181        f->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc(
     182            mrb, f->lines.flat_map,
     183            sizeof(mrb_irep_debug_info_line) * (f->line_entry_count + 1));
    187184        m.start_pos = start_pos + i;
    188         m.line = irep->lines[start_pos + i];
    189         ret->lines.flat_map[ret->line_entry_count] = m;
     185        m.line = lines[start_pos + i];
     186        f->lines.flat_map[f->line_entry_count] = m;
    190187
    191188        /* update */
    192         ++ret->line_entry_count;
    193         prev_line = irep->lines[start_pos + i];
     189        ++f->line_entry_count;
     190        prev_line = lines[start_pos + i];
    194191      }
    195192    } break;
     
    198195  }
    199196
    200   return ret;
     197  return f;
    201198}
    202199
  • EcnlProtoTool/trunk/mruby-2.1.1/src/dump.c

    r331 r439  
    77#include <string.h>
    88#include <limits.h>
     9#include <math.h>
    910#include <mruby/dump.h>
    1011#include <mruby/string.h>
     
    1617#define FLAG_BYTEORDER_NONATIVE 0
    1718
     19#ifndef MRB_WITHOUT_FLOAT
    1820#ifdef MRB_USE_FLOAT
    19 #define MRB_FLOAT_FMT "%.8e"
     21#define MRB_FLOAT_FMT "%.9g"
    2022#else
    21 #define MRB_FLOAT_FMT "%.16e"
     23#define MRB_FLOAT_FMT "%.17g"
     24#endif
    2225#endif
    2326
     
    8083{
    8184  uint8_t *cur = buf;
    82   uint32_t iseq_no;
    8385
    8486  cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */
    8587  cur += write_padding(cur);
    86   switch (flags & DUMP_ENDIAN_NAT) {
    87   case DUMP_ENDIAN_BIG:
    88     if (bigendian_p()) goto native;
    89     for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
    90       cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
    91     }
    92     break;
    93   case DUMP_ENDIAN_LIL:
    94     if (!bigendian_p()) goto native;
    95     for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
    96       cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */
    97     }
    98     break;
    99 
    100   native:
    101   case DUMP_ENDIAN_NAT:
    102     memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code));
    103     cur += irep->ilen * sizeof(mrb_code);
    104     break;
    105   }
     88  memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code));
     89  cur += irep->ilen * sizeof(mrb_code);
    10690
    10791  return cur - buf;
    10892}
    10993
     94#ifndef MRB_WITHOUT_FLOAT
     95static mrb_value
     96float_to_str(mrb_state *mrb, mrb_value flt)
     97{
     98  mrb_float f = mrb_float(flt);
     99
     100  if (isinf(f)) {
     101    return f < 0 ? mrb_str_new_lit(mrb, "I") : mrb_str_new_lit(mrb, "i");
     102  }
     103  return  mrb_float_to_str(mrb, flt, MRB_FLOAT_FMT);
     104}
     105#endif
    110106
    111107static size_t
    112108get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
    113109{
     110  int pool_no;
    114111  size_t size = 0;
    115   size_t pool_no;
    116112  mrb_value str;
    117113
     
    132128      break;
    133129
     130#ifndef MRB_WITHOUT_FLOAT
    134131    case MRB_TT_FLOAT:
    135       str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
     132      str = float_to_str(mrb, irep->pool[pool_no]);
    136133      {
    137134        mrb_int len = RSTRING_LEN(str);
     
    140137      }
    141138      break;
     139#endif
    142140
    143141    case MRB_TT_STRING:
     
    161159write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
    162160{
    163   size_t pool_no;
     161  int pool_no;
    164162  uint8_t *cur = buf;
    165163  uint16_t len;
     
    178176      break;
    179177
     178#ifndef MRB_WITHOUT_FLOAT
    180179    case MRB_TT_FLOAT:
    181180      cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
    182       str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
     181      str = float_to_str(mrb, irep->pool[pool_no]);
    183182      break;
     183#endif
    184184
    185185    case MRB_TT_STRING:
     
    214214{
    215215  size_t size = 0;
    216   uint32_t sym_no;
     216  int sym_no;
    217217  mrb_int len;
    218218
     
    221221    size += sizeof(uint16_t); /* snl(n) */
    222222    if (irep->syms[sym_no] != 0) {
    223       mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
     223      mrb_sym_name_len(mrb, irep->syms[sym_no], &len);
    224224      size += len + 1; /* sn(n) + null char */
    225225    }
     
    232232write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
    233233{
    234   uint32_t sym_no;
     234  int sym_no;
    235235  uint8_t *cur = buf;
    236236  const char *name;
     
    242242      mrb_int len;
    243243
    244       name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
     244      name = mrb_sym_name_len(mrb, irep->syms[sym_no], &len);
    245245
    246246      mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX);
     
    274274{
    275275  size_t size = 0;
    276   size_t irep_no;
     276  int irep_no;
    277277
    278278  size = get_irep_record_size_1(mrb, irep);
     
    286286write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *irep_record_size, uint8_t flags)
    287287{
    288   uint32_t i;
     288  int i;
    289289  uint8_t *src = bin;
    290290
     
    367367}
    368368
    369 static int
    370 write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin)
    371 {
    372   struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin;
    373 
    374   memcpy(header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(header->section_ident));
    375   uint32_to_bin((uint32_t)section_size, header->section_size);
    376 
    377   return MRB_DUMP_OK;
    378 }
    379 
    380 static size_t
    381 get_lineno_record_size(mrb_state *mrb, mrb_irep *irep)
    382 {
    383   size_t size = 0;
    384 
    385   size += sizeof(uint32_t); /* record size */
    386   size += sizeof(uint16_t); /* filename size */
    387   if (irep->filename) {
    388     size += strlen(irep->filename); /* filename */
    389   }
    390   size += sizeof(uint32_t); /* niseq */
    391   if (irep->lines) {
    392     size += sizeof(uint16_t) * irep->ilen; /* lineno */
    393   }
    394 
    395   return size;
    396 }
    397 
    398 static size_t
    399 write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
    400 {
    401   uint8_t *cur = bin;
    402   size_t iseq_no;
    403   size_t filename_len;
    404   ptrdiff_t diff;
    405 
    406   cur += sizeof(uint32_t); /* record size */
    407 
    408   if (irep->filename) {
    409     filename_len = strlen(irep->filename);
    410   }
    411   else {
    412     filename_len = 0;
    413   }
    414   mrb_assert_int_fit(size_t, filename_len, uint16_t, UINT16_MAX);
    415   cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */
    416 
    417   if (filename_len) {
    418     memcpy(cur, irep->filename, filename_len);
    419     cur += filename_len; /* filename */
    420   }
    421 
    422   if (irep->lines) {
    423     mrb_assert_int_fit(size_t, irep->ilen, uint32_t, UINT32_MAX);
    424     cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */
    425     for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
    426       cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */
    427     }
    428   }
    429   else {
    430     cur += uint32_to_bin(0, cur); /* niseq */
    431   }
    432 
    433   diff = cur - bin;
    434   mrb_assert_int_fit(ptrdiff_t, diff, uint32_t, UINT32_MAX);
    435 
    436   uint32_to_bin((uint32_t)diff, bin); /* record size */
    437 
    438   mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
    439   return (size_t)diff;
    440 }
    441 
    442 static size_t
    443 write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
    444 {
    445   size_t i;
    446   size_t rlen, size = 0;
    447 
    448   rlen = write_lineno_record_1(mrb, irep, bin);
    449   bin += rlen;
    450   size += rlen;
    451   for (i=0; i<irep->rlen; i++) {
    452     rlen = write_lineno_record(mrb, irep, bin);
    453     bin += rlen;
    454     size += rlen;
    455   }
    456   return size;
    457 }
    458 
    459 static int
    460 write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
    461 {
    462   size_t section_size = 0;
    463   size_t rlen = 0; /* size of irep record */
    464   uint8_t *cur = bin;
    465 
    466   if (mrb == NULL || bin == NULL) {
    467     return MRB_DUMP_INVALID_ARGUMENT;
    468   }
    469 
    470   cur += sizeof(struct rite_section_lineno_header);
    471   section_size += sizeof(struct rite_section_lineno_header);
    472 
    473   rlen = write_lineno_record(mrb, irep, cur);
    474   section_size += rlen;
    475 
    476   write_section_lineno_header(mrb, section_size, bin);
    477 
    478   return MRB_DUMP_OK;
    479 }
    480 
    481369static size_t
    482370get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
     
    484372  size_t ret = 0;
    485373  uint16_t f_idx;
    486   size_t i;
     374  int i;
    487375
    488376  ret += sizeof(uint32_t); /* record size */
     
    532420{
    533421  mrb_sym *filenames = *fp;
    534   size_t i, size = 0;
     422  size_t size = 0;
    535423  mrb_irep_debug_info *di = irep->debug_info;
     424  int i;
    536425
    537426  mrb_assert(lp);
     
    548437
    549438      /* filename */
    550       mrb_sym2name_len(mrb, file->filename_sym, &filename_len);
     439      mrb_sym_name_len(mrb, file->filename_sym, &filename_len);
    551440      size += sizeof(uint16_t) + (size_t)filename_len;
    552441    }
     
    606495  ret = cur - bin;
    607496  mrb_assert_int_fit(ptrdiff_t, ret, uint32_t, UINT32_MAX);
    608   uint32_to_bin(ret, bin);
     497  uint32_to_bin((uint32_t)ret, bin);
    609498
    610499  mrb_assert_int_fit(ptrdiff_t, ret, size_t, SIZE_MAX);
     
    616505{
    617506  size_t size, len;
    618   size_t irep_no;
     507  int irep_no;
    619508
    620509  size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len);
     
    652541  section_size += sizeof(uint16_t);
    653542  for (i = 0; i < filenames_len; ++i) {
    654     sym = mrb_sym2name_len(mrb, filenames[i], &sym_len);
     543    sym = mrb_sym_name_len(mrb, filenames[i], &sym_len);
    655544    mrb_assert(sym);
    656     cur += uint16_to_bin(sym_len, cur);
     545    cur += uint16_to_bin((uint16_t)sym_len, cur);
    657546    memcpy(cur, sym, sym_len);
    658547    cur += sym_len;
     
    666555  memcpy(header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(header->section_ident));
    667556  mrb_assert(section_size <= INT32_MAX);
    668   uint32_to_bin(section_size, header->section_size);
     557  uint32_to_bin((uint32_t)section_size, header->section_size);
    669558
    670559  return MRB_DUMP_OK;
     
    674563create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len)
    675564{
    676   size_t i;
     565  int i;
    677566
    678567  if (*syms == NULL) {
     
    706595
    707596  for (i = 0; i < syms_len; ++i) {
    708     str = mrb_sym2name_len(mrb, syms[i], &str_len);
    709     cur += uint16_to_bin(str_len, cur);
     597    str = mrb_sym_name_len(mrb, syms[i], &str_len);
     598    cur += uint16_to_bin((uint16_t)str_len, cur);
    710599    memcpy(cur, str, str_len);
    711600    cur += str_len;
     
    721610{
    722611  uint8_t *cur = *start;
    723   size_t i;
     612  int i;
    724613
    725614  for (i = 0; i + 1 < irep->nlocals; ++i) {
     
    749638get_lv_record_size(mrb_state *mrb, mrb_irep *irep)
    750639{
    751   size_t ret = 0, i;
     640  size_t ret = 0;
     641  int i;
    752642
    753643  ret += (sizeof(uint16_t) + sizeof(uint16_t)) * (irep->nlocals - 1);
     
    769659  for (i = 0; i < syms_len; ++i) {
    770660    mrb_int str_len;
    771     mrb_sym2name_len(mrb, syms[i], &str_len);
     661    mrb_sym_name_len(mrb, syms[i], &str_len);
    772662    ret += str_len;
    773663  }
     
    807697  diff = cur - start;
    808698  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
    809   uint32_to_bin(diff, header->section_size);
     699  uint32_to_bin((uint32_t)diff, header->section_size);
    810700
    811701lv_section_exit:
     
    842732  uint32_to_bin((uint32_t)binary_size, header->binary_size);
    843733
    844   offset = (&(header->binary_crc[0]) - bin) + sizeof(uint16_t);
     734  offset = (uint32_t)((&(header->binary_crc[0]) - bin) + sizeof(uint16_t));
    845735  crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0);
    846736  uint16_to_bin(crc, header->binary_crc);
     
    850740
    851741static mrb_bool
    852 is_debug_info_defined(mrb_irep *irep)
    853 {
    854   size_t i;
     742debug_info_defined_p(mrb_irep *irep)
     743{
     744  int i;
    855745
    856746  if (!irep->debug_info) return FALSE;
    857747  for (i=0; i<irep->rlen; i++) {
    858     if (!is_debug_info_defined(irep->reps[i])) return FALSE;
     748    if (!debug_info_defined_p(irep->reps[i])) return FALSE;
    859749  }
    860750  return TRUE;
     
    862752
    863753static mrb_bool
    864 is_lv_defined(mrb_irep *irep)
    865 {
    866   size_t i;
     754lv_defined_p(mrb_irep *irep)
     755{
     756  int i;
    867757
    868758  if (irep->lv) { return TRUE; }
    869759
    870760  for (i = 0; i < irep->rlen; ++i) {
    871     if (is_lv_defined(irep->reps[i])) { return TRUE; }
     761    if (lv_defined_p(irep->reps[i])) { return TRUE; }
    872762  }
    873763
     
    898788  size_t section_lineno_size = 0, section_lv_size = 0;
    899789  uint8_t *cur = NULL;
    900   mrb_bool const debug_info_defined = is_debug_info_defined(irep), lv_defined = is_lv_defined(irep);
     790  mrb_bool const debug_info_defined = debug_info_defined_p(irep), lv_defined = lv_defined_p(irep);
    901791  mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0;
    902792  mrb_sym *filenames = NULL; uint16_t filenames_len = 0;
     
    923813      section_lineno_size += get_debug_record_size(mrb, irep);
    924814    }
    925     else {
    926       section_lineno_size += sizeof(struct rite_section_lineno_header);
    927       section_lineno_size += get_lineno_record_size(mrb, irep);
    928     }
    929815  }
    930816
     
    954840    if (debug_info_defined) {
    955841      result = write_section_debug(mrb, irep, cur, filenames, filenames_len);
    956     }
    957     else {
    958       result = write_section_lineno(mrb, irep, cur);
    959     }
    960     if (result != MRB_DUMP_OK) {
    961       goto error_exit;
     842      if (result != MRB_DUMP_OK) {
     843        goto error_exit;
     844      }
    962845    }
    963846    cur += section_lineno_size;
     
    1061944    }
    1062945    if (fprintf(fp,
     946          "#ifdef __cplusplus\n"
    1063947          "extern const uint8_t %s[];\n"
     948          "#endif\n"
    1064949          "const uint8_t\n"
    1065950          "#if defined __GNUC__\n"
  • EcnlProtoTool/trunk/mruby-2.1.1/src/enum.c

    r331 r439  
    66
    77#include <mruby.h>
     8#include <mruby/proc.h>
     9
     10/* internal method `__update_hash(oldhash, index, itemhash)` */
     11static mrb_value
     12enum_update_hash(mrb_state *mrb, mrb_value self)
     13{
     14  mrb_int hash;
     15  mrb_int index;
     16  mrb_int hv;
     17
     18  mrb_get_args(mrb, "iii", &hash, &index, &hv);
     19  hash ^= ((uint32_t)hv << (index % 16));
     20
     21  return mrb_fixnum_value(hash);
     22}
    823
    924void
    1025mrb_init_enumerable(mrb_state *mrb)
    1126{
    12   mrb_define_module(mrb, "Enumerable");  /* 15.3.2 */
     27  struct RClass *enumerable;
     28  enumerable = mrb_define_module(mrb, "Enumerable");  /* 15.3.2 */
     29  mrb_define_module_function(mrb, enumerable, "__update_hash", enum_update_hash, MRB_ARGS_REQ(3));
    1330}
    14 
  • EcnlProtoTool/trunk/mruby-2.1.1/src/error.c

    r331 r439  
    1414#include <mruby/string.h>
    1515#include <mruby/variable.h>
    16 #include <mruby/debug.h>
    1716#include <mruby/error.h>
    1817#include <mruby/class.h>
     
    2928mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str)
    3029{
    31   str = mrb_str_to_str(mrb, str);
     30  mrb_to_str(mrb, str);
    3231  return mrb_obj_new(mrb, c, 1, &str);
    3332}
     
    4544{
    4645  mrb_value mesg;
    47   mrb_int argc;
    48   mrb_value *argv;
    49 
    50   if (mrb_get_args(mrb, "|o*", &mesg, &argv, &argc) >= 1) {
     46
     47  if (mrb_get_args(mrb, "|o", &mesg) == 1) {
    5148    mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg);
    5249  }
     
    7269  mrb_value exc;
    7370  mrb_value a;
    74   int argc;
     71  mrb_int argc;
    7572
    7673  argc = mrb_get_args(mrb, "|o", &a);
     
    9188 */
    9289
    93 static mrb_value
     90mrb_value
    9491exc_to_s(mrb_state *mrb, mrb_value exc)
    9592{
     
    131128 */
    132129
    133 static mrb_value
    134 exc_inspect(mrb_state *mrb, mrb_value exc)
    135 {
    136   mrb_value str, mesg, file, line;
    137   mrb_bool append_mesg;
    138   const char *cname;
    139 
    140   mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
    141   file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file"));
    142   line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line"));
    143 
    144   append_mesg = !mrb_nil_p(mesg);
    145   if (append_mesg) {
    146     mesg = mrb_obj_as_string(mrb, mesg);
    147     append_mesg = RSTRING_LEN(mesg) > 0;
    148   }
    149 
    150   cname = mrb_obj_classname(mrb, exc);
    151   str = mrb_str_new_cstr(mrb, cname);
    152   if (mrb_string_p(file) && mrb_fixnum_p(line)) {
    153     if (append_mesg) {
    154       str = mrb_format(mrb, "%S:%S:%S (%S)", file, line, mesg, str);
    155     }
    156     else {
    157       str = mrb_format(mrb, "%S:%S:%S", file, line, str);
    158     }
    159   }
    160   else if (append_mesg) {
    161     str = mrb_format(mrb, "%S:%S", str, mesg);
    162   }
    163   return str;
     130mrb_value
     131mrb_exc_inspect(mrb_state *mrb, mrb_value exc)
     132{
     133  mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
     134  mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc)));
     135  mesg = mrb_obj_as_string(mrb, mesg);
     136  return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname);
    164137}
    165138
     
    195168}
    196169
    197 static void
    198 exc_debug_info(mrb_state *mrb, struct RObject *exc)
    199 {
    200   mrb_callinfo *ci = mrb->c->ci;
    201   mrb_code *pc = ci->pc;
    202 
    203   while (ci >= mrb->c->cibase) {
    204     mrb_code *err = ci->err;
    205 
    206     if (!err && pc) err = pc - 1;
    207     if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
    208       mrb_irep *irep = ci->proc->body.irep;
    209 
    210       int32_t const line = mrb_debug_get_line(irep, (uint32_t)(err - irep->iseq));
    211       char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq));
    212       if (line != -1 && file) {
    213         mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));
    214         mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));
    215         return;
    216       }
    217     }
    218     pc = ci->pc;
    219     ci--;
    220   }
    221 }
    222 
    223170void
    224171mrb_exc_set(mrb_state *mrb, mrb_value exc)
     
    229176  else {
    230177    mrb->exc = mrb_obj_ptr(exc);
    231     if (!mrb->gc.out_of_memory) {
    232       exc_debug_info(mrb, mrb->exc);
     178    if (mrb->gc.arena_idx > 0 &&
     179        (struct RBasic*)mrb->exc == mrb->gc.arena[mrb->gc.arena_idx-1]) {
     180      mrb->gc.arena_idx--;
     181    }
     182    if (!mrb->gc.out_of_memory && !mrb_frozen_p(mrb->exc)) {
    233183      mrb_keep_backtrace(mrb, exc);
    234184    }
     
    239189mrb_exc_raise(mrb_state *mrb, mrb_value exc)
    240190{
    241   if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) {
    242     mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
    243   }
    244   mrb_exc_set(mrb, exc);
     191  if (mrb_break_p(exc)) {
     192    mrb->exc = mrb_obj_ptr(exc);
     193  }
     194  else {
     195    if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) {
     196      mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
     197    }
     198    mrb_exc_set(mrb, exc);
     199  }
    245200  if (!mrb->jmp) {
    246201    mrb_p(mrb, exc);
     
    256211}
    257212
     213/*
     214 * <code>vsprintf</code> like formatting.
     215 *
     216 * The syntax of a format sequence is as follows.
     217 *
     218 *   %[modifier]specifier
     219 *
     220 * The modifiers are:
     221 *
     222 *   ----------+------------------------------------------------------------
     223 *   Modifier  | Meaning
     224 *   ----------+------------------------------------------------------------
     225 *       !     | Convert to string by corresponding `inspect` instead of
     226 *             | corresponding `to_s`.
     227 *   ----------+------------------------------------------------------------
     228 *
     229 * The specifiers are:
     230 *
     231 *   ----------+----------------+--------------------------------------------
     232 *   Specifier | Argument Type  | Note
     233 *   ----------+----------------+--------------------------------------------
     234 *       c     | char           |
     235 *       d     | int            |
     236 *       f     | mrb_float      |
     237 *       i     | mrb_int        |
     238 *       l     | char*, size_t  | Arguments are string and length.
     239 *       n     | mrb_sym        |
     240 *       s     | char*          | Argument is NUL terminated string.
     241 *       t     | mrb_value      | Convert to type (class) of object.
     242 *      v,S    | mrb_value      |
     243 *       C     | struct RClass* |
     244 *       T     | mrb_value      | Convert to real type (class) of object.
     245 *       Y     | mrb_value      | Same as `!v` if argument is `true`, `false`
     246 *             |                | or `nil`, otherwise same as `T`.
     247 *       %     | -              | Convert to percent sign itself (no argument
     248 *             |                | taken).
     249 *   ----------+----------------+--------------------------------------------
     250 */
    258251MRB_API mrb_value
    259252mrb_vformat(mrb_state *mrb, const char *format, va_list ap)
    260253{
    261   const char *p = format;
    262   const char *b = p;
    263   ptrdiff_t size;
    264   mrb_value ary = mrb_ary_new_capa(mrb, 4);
     254  const char *chars, *p = format, *b = format, *e;
     255  char ch;
     256  size_t len;
     257  mrb_int i;
     258  struct RClass *cls;
     259  mrb_bool inspect = FALSE;
     260  mrb_value result = mrb_str_new_capa(mrb, 128), obj, str;
    265261  int ai = mrb_gc_arena_save(mrb);
    266262
    267263  while (*p) {
    268264    const char c = *p++;
    269 
     265    e = p;
    270266    if (c == '%') {
    271       if (*p == 'S') {
    272         size = p - b - 1;
    273         mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
    274         mrb_ary_push(mrb, ary, va_arg(ap, mrb_value));
    275         b = p + 1;
     267      if (*p == '!') {
     268        inspect = TRUE;
     269        ++p;
    276270      }
     271      if (!*p) break;
     272      switch (*p) {
     273        case 'c':
     274          ch = (char)va_arg(ap, int);
     275          chars = &ch;
     276          len = 1;
     277          goto L_cat;
     278        case 'd': case 'i':
     279#if MRB_INT_MAX < INT_MAX
     280          i = (mrb_int)va_arg(ap, int);
     281#else
     282          i = *p == 'd' ? (mrb_int)va_arg(ap, int) : va_arg(ap, mrb_int);
     283#endif
     284          obj = mrb_fixnum_value(i);
     285          goto L_cat_obj;
     286#ifndef MRB_WITHOUT_FLOAT
     287        case 'f':
     288          obj = mrb_float_value(mrb, (mrb_float)va_arg(ap, double));
     289          goto L_cat_obj;
     290#endif
     291        case 'l':
     292          chars = va_arg(ap, char*);
     293          len = va_arg(ap, size_t);
     294        L_cat:
     295          if (inspect) {
     296            obj = mrb_str_new(mrb, chars, len);
     297            goto L_cat_obj;
     298          }
     299          mrb_str_cat(mrb, result, b,  e - b - 1);
     300          mrb_str_cat(mrb, result, chars, len);
     301          b = ++p;
     302          mrb_gc_arena_restore(mrb, ai);
     303          break;
     304        case 'n':
     305#if UINT32_MAX < INT_MAX
     306          obj = mrb_symbol_value((mrb_sym)va_arg(ap, int));
     307#else
     308          obj = mrb_symbol_value(va_arg(ap, mrb_sym));
     309#endif
     310          goto L_cat_obj;
     311        case 's':
     312          chars = va_arg(ap, char*);
     313          len = strlen(chars);
     314          goto L_cat;
     315        case 't':
     316          cls = mrb_class(mrb, va_arg(ap, mrb_value));
     317          goto L_cat_class;
     318        case 'v': case 'S':
     319          obj = va_arg(ap, mrb_value);
     320        L_cat_obj:
     321          str = (inspect ? mrb_inspect : mrb_obj_as_string)(mrb, obj);
     322          chars = RSTRING_PTR(str);
     323          len = RSTRING_LEN(str);
     324          inspect = FALSE;
     325          goto L_cat;
     326        case 'C':
     327          cls = va_arg(ap, struct RClass*);
     328        L_cat_class:
     329          obj = mrb_obj_value(cls);
     330          goto L_cat_obj;
     331        case 'T':
     332          obj = va_arg(ap, mrb_value);
     333        L_cat_real_class_of:
     334          cls = mrb_obj_class(mrb, obj);
     335          goto L_cat_class;
     336        case 'Y':
     337          obj = va_arg(ap, mrb_value);
     338          if (!mrb_test(obj) || mrb_true_p(obj)) {
     339            inspect = TRUE;
     340            goto L_cat_obj;
     341          }
     342          else {
     343            goto L_cat_real_class_of;
     344          }
     345        case '%':
     346        L_cat_current:
     347          chars = p;
     348          len = 1;
     349          goto L_cat;
     350        default:
     351          mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p);
     352      }
    277353    }
    278354    else if (c == '\\') {
    279       if (*p) {
    280         size = p - b - 1;
    281         mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
    282         mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1));
    283         b = ++p;
    284       }
    285       else {
    286         break;
    287       }
    288     }
    289     mrb_gc_arena_restore(mrb, ai);
    290   }
    291   if (b == format) {
    292     return mrb_str_new_cstr(mrb, format);
    293   }
    294   else {
    295     size = p - b;
    296     if (size > 0) {
    297       mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
    298       mrb_gc_arena_restore(mrb, ai);
    299     }
    300     return mrb_ary_join(mrb, ary, mrb_nil_value());
    301   }
     355      if (!*p) break;
     356      goto L_cat_current;
     357
     358    }
     359  }
     360
     361  mrb_str_cat(mrb, result, b, p - b);
     362  return result;
    302363}
    303364
     
    319380{
    320381  mrb_value mesg;
     382  static int called = 0;
    321383
    322384  mesg = mrb_vformat(mrb, fmt, ap);
     
    327389    argv[0] = mesg;
    328390  }
     391  if (called)
     392    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
     393  called = 1;
    329394  mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv));
    330395}
     
    363428  fputs("warning: ", stderr);
    364429  fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr);
     430  putc('\n', stderr);
    365431  va_end(ap);
    366432#endif
     
    384450
    385451MRB_API mrb_value
    386 mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)
     452mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv)
    387453{
    388454  mrb_value mesg;
     
    420486      break;
    421487    default:
    422       mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc));
     488      mrb_argnum_error(mrb, argc, 0, 3);
    423489      break;
    424490  }
     
    470536}
    471537
     538MRB_API mrb_noreturn void
     539mrb_frozen_error(mrb_state *mrb, void *frozen_obj)
     540{
     541  mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj));
     542}
     543
     544MRB_API mrb_noreturn void
     545mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max)
     546{
     547#define FMT(exp) "wrong number of arguments (given %i, expected " exp ")"
     548  if (min == max)
     549    mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d"), argc, min);
     550  else if (max < 0)
     551    mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d+"), argc, min);
     552  else
     553    mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d..%d"), argc, min, max);
     554#undef FMT
     555}
     556
    472557void
    473558mrb_init_exception(mrb_state *mrb)
     
    477562  mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
    478563  MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION);
    479   mrb_define_class_method(mrb, exception, "exception", mrb_instance_new,  MRB_ARGS_ANY());
    480   mrb_define_method(mrb, exception, "exception",       exc_exception,     MRB_ARGS_ANY());
    481   mrb_define_method(mrb, exception, "initialize",      exc_initialize,    MRB_ARGS_ANY());
     564  mrb_define_class_method(mrb, exception, "exception", mrb_instance_new,  MRB_ARGS_OPT(1));
     565  mrb_define_method(mrb, exception, "exception",       exc_exception,     MRB_ARGS_OPT(1));
     566  mrb_define_method(mrb, exception, "initialize",      exc_initialize,    MRB_ARGS_OPT(1));
    482567  mrb_define_method(mrb, exception, "to_s",            exc_to_s,          MRB_ARGS_NONE());
    483568  mrb_define_method(mrb, exception, "message",         exc_message,       MRB_ARGS_NONE());
    484   mrb_define_method(mrb, exception, "inspect",         exc_inspect,       MRB_ARGS_NONE());
     569  mrb_define_method(mrb, exception, "inspect",         mrb_exc_inspect,   MRB_ARGS_NONE());
    485570  mrb_define_method(mrb, exception, "backtrace",       mrb_exc_backtrace, MRB_ARGS_NONE());
    486571  mrb_define_method(mrb, exception, "set_backtrace",   exc_set_backtrace, MRB_ARGS_REQ(1));
  • EcnlProtoTool/trunk/mruby-2.1.1/src/etc.c

    r331 r439  
    11/*
    2 ** etc.c -
     2** etc.c
    33**
    44** See Copyright Notice in mruby.h
     
    99#include <mruby/data.h>
    1010#include <mruby/class.h>
    11 #include <mruby/re.h>
    12 #include <mruby/irep.h>
    1311
    1412MRB_API struct RData*
     
    2725mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
    2826{
    29   if (mrb_type(obj) != MRB_TT_DATA) {
     27  if (!mrb_data_p(obj)) {
    3028    mrb_check_type(mrb, obj, MRB_TT_DATA);
    3129  }
     
    3432
    3533    if (t2) {
    36       mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
    37                  mrb_str_new_cstr(mrb, t2->struct_name), mrb_str_new_cstr(mrb, type->struct_name));
     34      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
     35                 t2->struct_name, type->struct_name);
    3836    }
    3937    else {
    40       struct RClass *c = mrb_class(mrb, obj);
    41 
    42       mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %S (expected %S)",
    43                  mrb_obj_value(c), mrb_str_new_cstr(mrb, type->struct_name));
     38      mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %t (expected %s)",
     39                 obj, type->struct_name);
    4440    }
    4541  }
     
    4945mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
    5046{
    51   if (mrb_type(obj) != MRB_TT_DATA) {
     47  if (!mrb_data_p(obj)) {
    5248    return NULL;
    5349  }
     
    6864mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
    6965{
    70   mrb_sym id;
    71 
    72   switch (mrb_type(name)) {
    73     default:
    74       name = mrb_check_string_type(mrb, name);
    75       if (mrb_nil_p(name)) {
    76         name = mrb_inspect(mrb, name);
    77         mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name);
    78       }
    79       /* fall through */
    80     case MRB_TT_STRING:
    81       name = mrb_str_intern(mrb, name);
    82       /* fall through */
    83     case MRB_TT_SYMBOL:
    84       id = mrb_symbol(name);
    85   }
    86   return id;
     66  if (mrb_symbol_p(name)) return mrb_symbol(name);
     67  if (mrb_string_p(name)) return mrb_intern_str(mrb, name);
     68  mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a symbol nor a string", name);
     69  return 0;  /* not reached */
    8770}
    8871
    8972MRB_API mrb_int
     73#ifdef MRB_WITHOUT_FLOAT
     74mrb_fixnum_id(mrb_int f)
     75#else
    9076mrb_float_id(mrb_float f)
     77#endif
    9178{
    9279  const char *p = (const char*)&f;
    9380  int len = sizeof(f);
    94   mrb_int id = 0;
    95 
     81  uint32_t id = 0;
     82
     83#ifndef MRB_WITHOUT_FLOAT
     84  /* normalize -0.0 to 0.0 */
     85  if (f == 0) f = 0.0;
     86#endif
    9687  while (len--) {
    9788    id = id*65599 + *p;
     
    10091  id = id + (id>>5);
    10192
    102   return id;
     93  return (mrb_int)id;
    10394}
    10495
     
    124115    return MakeID(mrb_symbol(obj));
    125116  case MRB_TT_FIXNUM:
     117#ifdef MRB_WITHOUT_FLOAT
     118    return MakeID(mrb_fixnum_id(mrb_fixnum(obj)));
     119#else
    126120    return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
    127121  case MRB_TT_FLOAT:
    128122    return MakeID(mrb_float_id(mrb_float(obj)));
     123#endif
    129124  case MRB_TT_STRING:
    130125  case MRB_TT_OBJECT:
     
    147142
    148143#ifdef MRB_WORD_BOXING
     144#ifndef MRB_WITHOUT_FLOAT
    149145MRB_API mrb_value
    150146mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
     
    154150  v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class);
    155151  v.value.fp->f = f;
     152  MRB_SET_FROZEN_FLAG(v.value.bp);
    156153  return v;
    157154}
     
    164161  nf->c = mrb->float_class;
    165162  nf->f = f;
     163  MRB_SET_FROZEN_FLAG(nf);
    166164  return mrb_obj_value(nf);
    167165}
     166#endif  /* MRB_WITHOUT_FLOAT */
    168167
    169168MRB_API mrb_value
     
    177176}
    178177#endif  /* MRB_WORD_BOXING */
    179 
    180 MRB_API mrb_bool
    181 mrb_regexp_p(mrb_state *mrb, mrb_value v)
    182 {
    183   if (mrb->flags & MRB_STATE_NO_REGEXP) {
    184     return FALSE;
    185   }
    186   if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) {
    187     mrb->flags |= MRB_STATE_REGEXP;
    188     return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS));
    189   }
    190   else {
    191     mrb->flags |= MRB_STATE_REGEXP;
    192     mrb->flags |= MRB_STATE_NO_REGEXP;
    193   }
    194   return FALSE;
    195 }
    196178
    197179#if defined _MSC_VER && _MSC_VER < 1900
  • EcnlProtoTool/trunk/mruby-2.1.1/src/fmt_fp.c

    r331 r439  
     1#ifndef MRB_WITHOUT_FLOAT
     2#if defined(MRB_DISABLE_STDIO) || defined(_WIN32) || defined(_WIN64)
    13/*
    24
     
    2931#include <limits.h>
    3032#include <string.h>
    31 #include <stdint.h>
    3233#include <math.h>
    3334#include <float.h>
     
    6263#define PAD_SIZE 256
    6364static void
    64 pad(struct fmt_args *f, char c, int w, int l, int fl)
     65pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl)
    6566{
    6667  char pad[PAD_SIZE];
     
    9293
    9394static int
    94 fmt_fp(struct fmt_args *f, long double y, int w, int p, int fl, int t)
     95fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t)
    9596{
    9697  uint32_t big[(LDBL_MANT_DIG+28)/29 + 1          // mantissa expansion
     
    9899  uint32_t *a, *d, *r, *z;
    99100  uint32_t i;
    100   int e2=0, e, j, l;
     101  int e2=0, e, j;
     102  ptrdiff_t l;
    101103  char buf[9+LDBL_MANT_DIG/4], *s;
    102104  const char *prefix="-0X+0X 0X-0x+0x 0x";
    103   int pl;
     105  ptrdiff_t pl;
    104106  char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
    105107
     
    116118    const char *ss = (t&32)?"inf":"INF";
    117119    if (y!=y) ss=(t&32)?"nan":"NAN";
    118     pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
     120    pad(f, ' ', 0, 3+pl, fl&~ZERO_PAD);
    119121    out(f, prefix, pl);
    120122    out(f, ss, 3);
    121     pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
    122     return MAX(w, 3+pl);
     123    pad(f, ' ', 0, 3+pl, fl^LEFT_ADJ);
     124    return 3+(int)pl;
    123125  }
    124126
     
    128130  if ((t|32)=='a') {
    129131    long double round = 8.0;
    130     int re;
     132    ptrdiff_t re;
    131133
    132134    if (t&32) prefix += 9;
     
    168170      l = (s-buf) + (ebuf-estr);
    169171
    170     pad(f, ' ', w, pl+l, fl);
     172    pad(f, ' ', 0, pl+l, fl);
    171173    out(f, prefix, pl);
    172     pad(f, '0', w, pl+l, fl^ZERO_PAD);
     174    pad(f, '0', 0, pl+l, fl^ZERO_PAD);
    173175    out(f, buf, s-buf);
    174176    pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
    175177    out(f, estr, ebuf-estr);
    176     pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
    177     return MAX(w, pl+l);
     178    pad(f, ' ', 0, pl+l, fl^LEFT_ADJ);
     179    return (int)pl+(int)l;
    178180  }
    179181  if (p<0) p=6;
     
    203205  while (e2<0) {
    204206    uint32_t carry=0, *b;
    205     int sh=MIN(9,-e2), need=1+(p+LDBL_MANT_DIG/3+8)/9;
     207    int sh=MIN(9,-e2), need=1+((int)p+LDBL_MANT_DIG/3+8)/9;
    206208    for (d=a; d<z; d++) {
    207209      uint32_t rm = *d & ((1<<sh)-1);
     
    217219  }
    218220
    219   if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
     221  if (a<z) for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++);
    220222  else e=0;
    221223
    222224  /* Perform rounding: j is precision after the radix (possibly neg) */
    223   j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
     225  j = (int)p - ((t|32)!='f')*e - ((t|32)=='g' && p);
    224226  if (j < 9*(z-r-1)) {
    225227    uint32_t x;
     
    248250          (*d)++;
    249251        }
    250         for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
     252        for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++);
    251253      }
    252254    }
     
    287289  }
    288290
    289   pad(f, ' ', w, pl+l, fl);
     291  pad(f, ' ', 0, pl+l, fl);
    290292  out(f, prefix, pl);
    291   pad(f, '0', w, pl+l, fl^ZERO_PAD);
     293  pad(f, '0', 0, pl+l, fl^ZERO_PAD);
    292294
    293295  if ((t|32)=='f') {
     
    318320      }
    319321      out(f, ss, MIN(buf+9-ss, p));
    320       p -= buf+9-ss;
     322      p -= (int)(buf+9-ss);
    321323    }
    322324    pad(f, '0', p+18, 18, 0);
     
    324326  }
    325327
    326   pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
    327 
    328   return MAX(w, pl+l);
     328  pad(f, ' ', 0, pl+l, fl^LEFT_ADJ);
     329
     330  return (int)pl+(int)l;
    329331}
    330332
     
    332334fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo)
    333335{
    334   int p;
     336  ptrdiff_t p;
    335337
    336338  if (*fmt != '%') {
     
    352354  case 'e': case 'f': case 'g': case 'a':
    353355  case 'E': case 'F': case 'G': case 'A':
    354     return fmt_fp(f, flo, 0, p, 0, *fmt);
     356    return fmt_fp(f, flo, p, 0, *fmt);
    355357  default:
    356358    return -1;
     
    364366
    365367  f.mrb = mrb;
    366   f.str = mrb_str_buf_new(mrb, 24);
     368  f.str = mrb_str_new_capa(mrb, 24);
    367369  if (fmt_core(&f, fmt, mrb_float(flo)) < 0) {
    368370    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string");
     
    370372  return f.str;
    371373}
     374#else   /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
     375#include <mruby.h>
     376#include <stdio.h>
     377
     378mrb_value
     379mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
     380{
     381  char buf[25];
     382
     383  snprintf(buf, sizeof(buf), fmt, mrb_float(flo));
     384  return mrb_str_new_cstr(mrb, buf);
     385}
     386#endif  /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */
     387#endif
  • EcnlProtoTool/trunk/mruby-2.1.1/src/gc.c

    r331 r439  
    1111#include <mruby/class.h>
    1212#include <mruby/data.h>
     13#include <mruby/istruct.h>
    1314#include <mruby/hash.h>
    1415#include <mruby/proc.h>
     
    110111    struct RRange range;
    111112    struct RData data;
     113    struct RIStruct istruct;
    112114    struct RProc proc;
    113115    struct REnv env;
     116    struct RFiber fiber;
    114117    struct RException exc;
    115118    struct RBreak brk;
    116119#ifdef MRB_WORD_BOXING
     120#ifndef MRB_WITHOUT_FLOAT
    117121    struct RFloat floatv;
     122#endif
    118123    struct RCptr cptr;
    119124#endif
     
    176181#define GC_STEP_SIZE 1024
    177182
    178 /* white: 011, black: 100, gray: 000 */
     183/* white: 001 or 010, black: 100, gray: 000 */
    179184#define GC_GRAY 0
    180185#define GC_WHITE_A 1
     
    273278}
    274279
     280MRB_API void*
     281mrb_alloca(mrb_state *mrb, size_t size)
     282{
     283  struct RString *s;
     284  s = (struct RString*)mrb_obj_alloc(mrb, MRB_TT_STRING, mrb->string_class);
     285  return s->as.heap.ptr = (char*)mrb_malloc(mrb, size);
     286}
     287
     288static mrb_bool
     289heap_p(mrb_gc *gc, struct RBasic *object)
     290{
     291  mrb_heap_page* page;
     292
     293  page = gc->heaps;
     294  while (page) {
     295    RVALUE *p;
     296
     297    p = objects(page);
     298    if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) {
     299      return TRUE;
     300    }
     301    page = page->next;
     302  }
     303  return FALSE;
     304}
     305
    275306MRB_API mrb_bool
    276307mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) {
    277   return is_dead(&mrb->gc, object);
     308  mrb_gc *gc = &mrb->gc;
     309  if (!heap_p(gc, object)) return TRUE;
     310  return is_dead(gc, object);
    278311}
    279312
     
    343376#define DEFAULT_GC_INTERVAL_RATIO 200
    344377#define DEFAULT_GC_STEP_RATIO 200
    345 #define DEFAULT_MAJOR_GC_INC_RATIO 200
     378#define MAJOR_GC_INC_RATIO 120
     379#define MAJOR_GC_TOOMANY 10000
    346380#define is_generational(gc) ((gc)->generational)
    347381#define is_major_gc(gc) (is_generational(gc) && (gc)->full)
     
    374408static void obj_free(mrb_state *mrb, struct RBasic *obj, int end);
    375409
    376 void
     410static void
    377411free_heap(mrb_state *mrb, mrb_gc *gc)
    378412{
     
    413447  if (gc->arena_idx >= gc->arena_capa) {
    414448    /* extend arena */
    415     gc->arena_capa = (int)(gc->arena_capa * 1.5);
     449    gc->arena_capa = (int)(gc->arena_capa * 3 / 2);
    416450    gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa);
    417451  }
     
    441475mrb_gc_register(mrb_state *mrb, mrb_value obj)
    442476{
    443   mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
    444   mrb_value table = mrb_gv_get(mrb, root);
    445 
    446   if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) {
     477  mrb_sym root;
     478  mrb_value table;
     479
     480  if (mrb_immediate_p(obj)) return;
     481  root = mrb_intern_lit(mrb, GC_ROOT_NAME);
     482  table = mrb_gv_get(mrb, root);
     483  if (mrb_nil_p(table) || !mrb_array_p(table)) {
    447484    table = mrb_ary_new(mrb);
    448485    mrb_gv_set(mrb, root, table);
     
    455492mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
    456493{
    457   mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
    458   mrb_value table = mrb_gv_get(mrb, root);
     494  mrb_sym root;
     495  mrb_value table;
    459496  struct RArray *a;
    460497  mrb_int i;
    461498
     499  if (mrb_immediate_p(obj)) return;
     500  root = mrb_intern_lit(mrb, GC_ROOT_NAME);
     501  table = mrb_gv_get(mrb, root);
    462502  if (mrb_nil_p(table)) return;
    463   if (mrb_type(table) != MRB_TT_ARRAY) {
     503  if (!mrb_array_p(table)) {
    464504    mrb_gv_set(mrb, root, mrb_nil_value());
    465505    return;
     
    467507  a = mrb_ary_ptr(table);
    468508  mrb_ary_modify(mrb, a);
    469   for (i = 0; i < a->len; i++) {
    470     if (mrb_obj_eq(mrb, a->ptr[i], obj)) {
    471       a->len--;
    472       memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i]));
     509  for (i = 0; i < ARY_LEN(a); i++) {
     510    if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) {
     511      mrb_int len = ARY_LEN(a)-1;
     512      mrb_value *ptr = ARY_PTR(a);
     513
     514      ARY_SET_LEN(a, len);
     515      memmove(&ptr[i], &ptr[i + 1], (len - i) * sizeof(mrb_value));
    473516      break;
    474517    }
     
    480523{
    481524  struct RBasic *p;
    482   static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };
     525  static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } };
    483526  mrb_gc *gc = &mrb->gc;
    484527
     
    501544        ttype != MRB_TT_ENV &&
    502545        ttype != tt) {
    503       mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls));
     546      mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls);
    504547    }
    505548  }
     
    543586}
    544587
     588static int
     589ci_nregs(mrb_callinfo *ci)
     590{
     591  struct RProc *p = ci->proc;
     592  int n = 0;
     593
     594  if (!p) {
     595    if (ci->argc < 0) return 3;
     596    return ci->argc+2;
     597  }
     598  if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
     599    n = p->body.irep->nregs;
     600  }
     601  if (ci->argc < 0) {
     602    if (n < 3) n = 3; /* self + args + blk */
     603  }
     604  if (ci->argc > n) {
     605    n = ci->argc + 2; /* self + blk */
     606  }
     607  return n;
     608}
     609
    545610static void
    546611mark_context_stack(mrb_state *mrb, struct mrb_context *c)
     
    549614  size_t e;
    550615  mrb_value nil;
    551   int nregs;
    552616
    553617  if (c->stack == NULL) return;
    554618  e = c->stack - c->stbase;
    555619  if (c->ci) {
    556     nregs = c->ci->argc + 2;
    557     if (c->ci->nregs > nregs)
    558       nregs = c->ci->nregs;
    559     e += nregs;
     620    e += ci_nregs(c->ci);
    560621  }
    561622  if (c->stbase + e > c->stend) e = c->stend - c->stbase;
     
    579640  int i;
    580641  mrb_callinfo *ci;
     642
     643 start:
     644  if (c->status == MRB_FIBER_TERMINATED) return;
    581645
    582646  /* mark VM stack */
     
    592656  }
    593657  /* mark ensure stack */
    594   for (i=0; i<c->esize; i++) {
    595     if (c->ensure[i] == NULL) break;
     658  for (i=0; i<c->eidx; i++) {
    596659    mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]);
    597660  }
     
    599662  mrb_gc_mark(mrb, (struct RBasic*)c->fib);
    600663  if (c->prev) {
    601     mark_context(mrb, c->prev);
     664    c = c->prev;
     665    goto start;
    602666  }
    603667}
     
    614678    {
    615679      struct RClass *c = (struct RClass*)obj;
    616       if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN))
     680      if (MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_ORIGIN))
    617681        mrb_gc_mark_mt(mrb, c);
    618682      mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super);
     
    641705      struct RProc *p = (struct RProc*)obj;
    642706
    643       mrb_gc_mark(mrb, (struct RBasic*)p->env);
    644       mrb_gc_mark(mrb, (struct RBasic*)p->target_class);
     707      mrb_gc_mark(mrb, (struct RBasic*)p->upper);
     708      mrb_gc_mark(mrb, (struct RBasic*)p->e.env);
    645709    }
    646710    break;
     
    651715      mrb_int i, len;
    652716
    653       if (MRB_ENV_STACK_SHARED_P(e)) {
    654         if (e->cxt.c->fib) {
    655           mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib);
    656         }
    657         break;
     717      if (MRB_ENV_STACK_SHARED_P(e) && e->cxt && e->cxt->fib) {
     718        mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib);
    658719      }
    659720      len = MRB_ENV_STACK_LEN(e);
     
    677738      size_t i, e;
    678739
    679       for (i=0,e=a->len; i<e; i++) {
    680         mrb_gc_mark_value(mrb, a->ptr[i]);
     740      for (i=0,e=ARY_LEN(a); i<e; i++) {
     741        mrb_gc_mark_value(mrb, ARY_PTR(a)[i]);
    681742      }
    682743    }
     
    689750
    690751  case MRB_TT_STRING:
     752    if (RSTR_FSHARED_P(obj)) {
     753      struct RString *s = (struct RString*)obj;
     754      mrb_gc_mark(mrb, (struct RBasic*)s->as.heap.aux.fshared);
     755    }
    691756    break;
    692757
    693758  case MRB_TT_RANGE:
    694     {
    695       struct RRange *r = (struct RRange*)obj;
    696 
    697       if (r->edges) {
    698         mrb_gc_mark_value(mrb, r->edges->beg);
    699         mrb_gc_mark_value(mrb, r->edges->end);
    700       }
    701     }
     759    mrb_gc_mark_range(mrb, (struct RRange*)obj);
    702760    break;
    703761
     
    728786    return;
    729787
     788#ifndef MRB_WITHOUT_FLOAT
    730789  case MRB_TT_FLOAT:
    731790#ifdef MRB_WORD_BOXING
     
    733792#else
    734793    return;
     794#endif
    735795#endif
    736796
     
    748808    mrb_gc_free_mt(mrb, (struct RClass*)obj);
    749809    mrb_gc_free_iv(mrb, (struct RObject*)obj);
     810    mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
    750811    break;
    751812  case MRB_TT_ICLASS:
    752     if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN))
     813    if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN))
    753814      mrb_gc_free_mt(mrb, (struct RClass*)obj);
     815    mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
    754816    break;
    755817  case MRB_TT_ENV:
     
    759821      if (MRB_ENV_STACK_SHARED_P(e)) {
    760822        /* cannot be freed */
    761         return;
     823        e->stack = NULL;
     824        break;
    762825      }
    763826      mrb_free(mrb, e->stack);
     
    770833      struct mrb_context *c = ((struct RFiber*)obj)->cxt;
    771834
    772       if (!end && c && c != mrb->root_c) {
    773         mrb_callinfo *ci = c->ci;
    774         mrb_callinfo *ce = c->cibase;
    775 
    776         while (ce <= ci) {
    777           struct REnv *e = ci->env;
    778           if (e && !is_dead(&mrb->gc, e) &&
    779               e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) {
    780             mrb_env_unshare(mrb, e);
     835      if (c && c != mrb->root_c) {
     836        if (!end && c->status != MRB_FIBER_TERMINATED) {
     837          mrb_callinfo *ci = c->ci;
     838          mrb_callinfo *ce = c->cibase;
     839
     840          while (ce <= ci) {
     841            struct REnv *e = ci->env;
     842            if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) &&
     843                e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) {
     844              mrb_env_unshare(mrb, e);
     845            }
     846            ci--;
    781847          }
    782           ci--;
    783848        }
    784849        mrb_free_context(mrb, c);
     
    789854  case MRB_TT_ARRAY:
    790855    if (ARY_SHARED_P(obj))
    791       mrb_ary_decref(mrb, ((struct RArray*)obj)->aux.shared);
    792     else
    793       mrb_free(mrb, ((struct RArray*)obj)->ptr);
     856      mrb_ary_decref(mrb, ((struct RArray*)obj)->as.heap.aux.shared);
     857    else if (!ARY_EMBED_P(obj))
     858      mrb_free(mrb, ((struct RArray*)obj)->as.heap.ptr);
    794859    break;
    795860
     
    808873
    809874      if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
    810         mrb_irep_decref(mrb, p->body.irep);
     875        mrb_irep *irep = p->body.irep;
     876        if (end) {
     877          mrb_irep_cutref(mrb, irep);
     878        }
     879        mrb_irep_decref(mrb, irep);
    811880      }
    812881    }
     
    814883
    815884  case MRB_TT_RANGE:
    816     mrb_free(mrb, ((struct RRange*)obj)->edges);
     885    mrb_gc_free_range(mrb, ((struct RRange*)obj));
    817886    break;
    818887
     
    858927  mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class);
    859928  mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class);
    860 
     929  mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class);
     930
     931#ifndef MRB_WITHOUT_FLOAT
    861932  mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class);
     933#endif
    862934  mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class);
    863935  mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class);
     
    918990
    919991  case MRB_TT_ENV:
    920     children += (int)obj->flags;
     992    children += MRB_ENV_STACK_LEN(obj);
    921993    break;
    922994
     
    927999      mrb_callinfo *ci;
    9281000
    929       if (!c) break;
     1001      if (!c || c->status == MRB_FIBER_TERMINATED) break;
     1002
    9301003      /* mark stack */
    9311004      i = c->stack - c->stbase;
    932       if (c->ci) i += c->ci->nregs;
     1005
     1006      if (c->ci) {
     1007        i += ci_nregs(c->ci);
     1008      }
    9331009      if (c->stbase + i > c->stend) i = c->stend - c->stbase;
    9341010      children += i;
     
    9491025    {
    9501026      struct RArray *a = (struct RArray*)obj;
    951       children += a->len;
     1027      children += ARY_LEN(a);
    9521028    }
    9531029    break;
     
    11901266
    11911267    if (is_major_gc(gc)) {
    1192       gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
     1268      size_t threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO;
     1269
    11931270      gc->full = FALSE;
     1271      if (threshold < MAJOR_GC_TOOMANY) {
     1272        gc->majorgc_old_threshold = threshold;
     1273      }
     1274      else {
     1275        /* too many objects allocated during incremental GC, */
     1276        /* instead of increasing threshold, invoke full GC. */
     1277        mrb_full_gc(mrb);
     1278      }
    11941279    }
    11951280    else if (is_minor_gc(gc)) {
     
    12291314
    12301315  if (is_generational(gc)) {
    1231     gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
     1316    gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO;
    12321317    gc->full = FALSE;
    12331318  }
     
    12401325{
    12411326  mrb_full_gc(mrb);
    1242 }
    1243 
    1244 MRB_API int
    1245 mrb_gc_arena_save(mrb_state *mrb)
    1246 {
    1247   return mrb->gc.arena_idx;
    1248 }
    1249 
    1250 MRB_API void
    1251 mrb_gc_arena_restore(mrb_state *mrb, int idx)
    1252 {
    1253   mrb_gc *gc = &mrb->gc;
    1254 
    1255 #ifndef MRB_GC_FIXED_ARENA
    1256   int capa = gc->arena_capa;
    1257 
    1258   if (idx < capa / 2) {
    1259     capa = (int)(capa * 0.66);
    1260     if (capa < MRB_GC_ARENA_SIZE) {
    1261       capa = MRB_GC_ARENA_SIZE;
    1262     }
    1263     if (capa != gc->arena_capa) {
    1264       gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa);
    1265       gc->arena_capa = capa;
    1266     }
    1267   }
    1268 #endif
    1269   gc->arena_idx = idx;
    12701327}
    12711328
     
    14071464
    14081465  mrb_get_args(mrb, "i", &ratio);
    1409   mrb->gc.interval_ratio = ratio;
     1466  mrb->gc.interval_ratio = (int)ratio;
    14101467  return mrb_nil_value();
    14111468}
     
    14401497
    14411498  mrb_get_args(mrb, "i", &ratio);
    1442   mrb->gc.step_ratio = ratio;
     1499  mrb->gc.step_ratio = (int)ratio;
    14431500  return mrb_nil_value();
    14441501}
     
    14581515  else if (!is_generational(gc) && enable) {
    14591516    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
    1460     gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
     1517    gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO;
    14611518    gc->full = FALSE;
    14621519  }
     
    15231580  mrb_bool iterating = mrb->gc.iterating;
    15241581
     1582  mrb_full_gc(mrb);
    15251583  mrb->gc.iterating = TRUE;
    15261584  if (iterating) {
     
    15351593      gc_each_objects(mrb, &mrb->gc, callback, data);
    15361594      mrb->jmp = prev_jmp;
    1537       mrb->gc.iterating = iterating; 
     1595      mrb->gc.iterating = iterating;
    15381596   } MRB_CATCH(&c_jmp) {
    15391597      mrb->gc.iterating = iterating;
     
    15541612{
    15551613  struct RClass *gc;
     1614
     1615  mrb_static_assert(sizeof(RVALUE) <= sizeof(void*) * 6,
     1616                    "RVALUE size must be within 6 words");
    15561617
    15571618  gc = mrb_define_module(mrb, "GC");
  • EcnlProtoTool/trunk/mruby-2.1.1/src/hash.c

    r331 r439  
    99#include <mruby/class.h>
    1010#include <mruby/hash.h>
    11 #include <mruby/khash.h>
    1211#include <mruby/string.h>
    1312#include <mruby/variable.h>
    1413
     14#ifndef MRB_WITHOUT_FLOAT
    1515/* a function to get hash value of a float number */
    1616mrb_int mrb_float_id(mrb_float f);
    17 
    18 static inline khint_t
    19 mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
    20 {
    21   enum mrb_vtype t = mrb_type(key);
     17#endif
     18
     19#ifndef MRB_HT_INIT_SIZE
     20#define MRB_HT_INIT_SIZE 4
     21#endif
     22#define HT_SEG_INCREASE_RATIO 6 / 5
     23
     24struct segkv {
     25  mrb_value key;
     26  mrb_value val;
     27};
     28
     29typedef struct segment {
     30  uint16_t size;
     31  struct segment *next;
     32  struct segkv e[];
     33} segment;
     34
     35typedef struct segindex {
     36  size_t size;
     37  size_t capa;
     38  struct segkv *table[];
     39} segindex;
     40
     41/* hash table structure */
     42typedef struct htable {
     43  segment *rootseg;
     44  segment *lastseg;
     45  mrb_int size;
     46  uint16_t last_len;
     47  segindex *index;
     48} htable;
     49
     50static /* inline */ size_t
     51ht_hash_func(mrb_state *mrb, htable *t, mrb_value key)
     52{
     53  enum mrb_vtype tt = mrb_type(key);
    2254  mrb_value hv;
    23   const char *p;
    24   mrb_int i, len;
    25   khint_t h;
    26 
    27   switch (t) {
     55  size_t h;
     56  segindex *index = t->index;
     57  size_t capa = index ? index->capa : 0;
     58
     59  switch (tt) {
    2860  case MRB_TT_STRING:
    29     p = RSTRING_PTR(key);
    30     len = RSTRING_LEN(key);
    31     h = 0;
    32     for (i=0; i<len; i++) {
    33       h = (h << 5) - h + *p++;
    34     }
    35     return h;
    36 
     61    h = mrb_str_hash(mrb, key);
     62    break;
     63
     64  case MRB_TT_TRUE:
     65  case MRB_TT_FALSE:
    3766  case MRB_TT_SYMBOL:
    38     h = (khint_t)mrb_symbol(key);
    39     return kh_int_hash_func(mrb, h);
    40 
    4167  case MRB_TT_FIXNUM:
    42     h = (khint_t)mrb_float_id((mrb_float)mrb_fixnum(key));
    43     return kh_int_hash_func(mrb, h);
    44 
     68#ifndef MRB_WITHOUT_FLOAT
    4569  case MRB_TT_FLOAT:
    46     h = (khint_t)mrb_float_id(mrb_float(key));
    47     return kh_int_hash_func(mrb, h);
     70#endif
     71    h = (size_t)mrb_obj_id(key);
     72    break;
    4873
    4974  default:
    5075    hv = mrb_funcall(mrb, key, "hash", 0);
    51     h = (khint_t)t ^ mrb_fixnum(hv);
    52     return kh_int_hash_func(mrb, h);
    53   }
    54 }
    55 
    56 static inline khint_t
    57 mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b)
    58 {
    59   enum mrb_vtype t = mrb_type(a);
    60 
    61   switch (t) {
     76    h = (size_t)t ^ (size_t)mrb_fixnum(hv);
     77    break;
     78  }
     79  if (index && (index != t->index || capa != index->capa)) {
     80    mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified");
     81  }
     82  return ((h)^((h)<<2)^((h)>>2));
     83}
     84
     85static inline mrb_bool
     86ht_hash_equal(mrb_state *mrb, htable *t, mrb_value a, mrb_value b)
     87{
     88  enum mrb_vtype tt = mrb_type(a);
     89
     90  switch (tt) {
    6291  case MRB_TT_STRING:
    6392    return mrb_str_equal(mrb, a, b);
    6493
    6594  case MRB_TT_SYMBOL:
    66     if (mrb_type(b) != MRB_TT_SYMBOL) return FALSE;
     95    if (!mrb_symbol_p(b)) return FALSE;
    6796    return mrb_symbol(a) == mrb_symbol(b);
    6897
     
    71100    case MRB_TT_FIXNUM:
    72101      return mrb_fixnum(a) == mrb_fixnum(b);
     102#ifndef MRB_WITHOUT_FLOAT
    73103    case MRB_TT_FLOAT:
    74104      return (mrb_float)mrb_fixnum(a) == mrb_float(b);
     105#endif
    75106    default:
    76107      return FALSE;
    77108    }
    78109
     110#ifndef MRB_WITHOUT_FLOAT
    79111  case MRB_TT_FLOAT:
    80112    switch (mrb_type(b)) {
     
    86118      return FALSE;
    87119    }
     120#endif
    88121
    89122  default:
    90     return mrb_eql(mrb, a, b);
    91   }
    92 }
    93 
    94 KHASH_DEFINE (ht, mrb_value, mrb_hash_value, TRUE, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal)
     123    {
     124      segindex *index = t->index;
     125      size_t capa = index ? index->capa : 0;
     126      mrb_bool eql = mrb_eql(mrb, a, b);
     127      if (index && (index != t->index || capa != index->capa)) {
     128        mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified");
     129      }
     130      return eql;
     131    }
     132  }
     133}
     134
     135/* Creates the hash table. */
     136static htable*
     137ht_new(mrb_state *mrb)
     138{
     139  htable *t;
     140
     141  t = (htable*)mrb_malloc(mrb, sizeof(htable));
     142  t->size = 0;
     143  t->rootseg =  NULL;
     144  t->lastseg =  NULL;
     145  t->last_len = 0;
     146  t->index = NULL;
     147
     148  return t;
     149}
     150
     151#define power2(v) do { \
     152  v--;\
     153  v |= v >> 1;\
     154  v |= v >> 2;\
     155  v |= v >> 4;\
     156  v |= v >> 8;\
     157  v |= v >> 16;\
     158  v++;\
     159} while (0)
     160
     161#ifndef UPPER_BOUND
     162#define UPPER_BOUND(x) ((x)>>2|(x)>>1)
     163#endif
     164
     165#define HT_MASK(index) ((index->capa)-1)
     166
     167/* Build index for the hash table */
     168static void
     169ht_index(mrb_state *mrb, htable *t)
     170{
     171  size_t size = (size_t)t->size;
     172  size_t mask;
     173  segindex *index = t->index;
     174  segment *seg;
     175  size_t i;
     176
     177  /* allocate index table */
     178  if (index && index->size >= UPPER_BOUND(index->capa)) {
     179    size = index->capa+1;
     180  }
     181  power2(size);
     182  if (!index || index->capa < size) {
     183    index = (segindex*)mrb_realloc_simple(mrb, index, sizeof(segindex)+sizeof(struct segkv*)*size);
     184    if (index == NULL) {
     185      mrb_free(mrb, t->index);
     186      t->index = NULL;
     187      return;
     188    }
     189    t->index = index;
     190  }
     191  index->size = t->size;
     192  index->capa = size;
     193  for (i=0; i<size; i++) {
     194    index->table[i] = NULL;
     195  }
     196
     197  /* rebuld index */
     198  mask = HT_MASK(index);
     199  seg = t->rootseg;
     200  while (seg) {
     201    for (i=0; i<seg->size; i++) {
     202      mrb_value key;
     203      size_t k, step = 0;
     204
     205      if (!seg->next && i >= (size_t)t->last_len) {
     206        return;
     207      }
     208      key = seg->e[i].key;
     209      if (mrb_undef_p(key)) continue;
     210      k = ht_hash_func(mrb, t, key) & mask;
     211      while (index->table[k]) {
     212        k = (k+(++step)) & mask;
     213      }
     214      index->table[k] = &seg->e[i];
     215    }
     216    seg = seg->next;
     217  }
     218}
     219
     220/* Compacts the hash table removing deleted entries. */
     221static void
     222ht_compact(mrb_state *mrb, htable *t)
     223{
     224  segment *seg;
     225  uint16_t i, i2;
     226  segment *seg2 = NULL;
     227  mrb_int size = 0;
     228
     229  if (t == NULL) return;
     230  seg = t->rootseg;
     231  if (t->index && (size_t)t->size == t->index->size) {
     232    ht_index(mrb, t);
     233    return;
     234  }
     235  while (seg) {
     236    for (i=0; i<seg->size; i++) {
     237      mrb_value k = seg->e[i].key;
     238
     239      if (!seg->next && i >= t->last_len) {
     240        goto exit;
     241      }
     242      if (mrb_undef_p(k)) {     /* found deleted key */
     243        if (seg2 == NULL) {
     244          seg2 = seg;
     245          i2 = i;
     246        }
     247      }
     248      else {
     249        size++;
     250        if (seg2 != NULL) {
     251          seg2->e[i2++] = seg->e[i];
     252          if (i2 >= seg2->size) {
     253            seg2 = seg2->next;
     254            i2 = 0;
     255          }
     256        }
     257      }
     258    }
     259    seg = seg->next;
     260  }
     261 exit:
     262  /* reached at end */
     263  t->size = size;
     264  if (seg2) {
     265    seg = seg2->next;
     266    seg2->next = NULL;
     267    t->last_len = i2;
     268    t->lastseg = seg2;
     269    while (seg) {
     270      seg2 = seg->next;
     271      mrb_free(mrb, seg);
     272      seg = seg2;
     273    }
     274  }
     275  if (t->index) {
     276    ht_index(mrb, t);
     277  }
     278}
     279
     280static segment*
     281segment_alloc(mrb_state *mrb, segment *seg)
     282{
     283  uint32_t size;
     284
     285  if (!seg) size = MRB_HT_INIT_SIZE;
     286  else {
     287    size = seg->size*HT_SEG_INCREASE_RATIO + 1;
     288    if (size > UINT16_MAX) size = UINT16_MAX;
     289  }
     290
     291  seg = (segment*)mrb_malloc(mrb, sizeof(segment)+sizeof(struct segkv)*size);
     292  seg->size = size;
     293  seg->next = NULL;
     294
     295  return seg;
     296}
     297
     298/* Set the value for the key in the indexed table. */
     299static void
     300ht_index_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
     301{
     302  segindex *index = t->index;
     303  size_t k, sp, step = 0, mask;
     304  segment *seg;
     305
     306  if (index->size >= UPPER_BOUND(index->capa)) {
     307    /* need to expand table */
     308    ht_compact(mrb, t);
     309    index = t->index;
     310  }
     311  mask = HT_MASK(index);
     312  sp = index->capa;
     313  k = ht_hash_func(mrb, t, key) & mask;
     314  while (index->table[k]) {
     315    mrb_value key2 = index->table[k]->key;
     316    if (mrb_undef_p(key2)) {
     317      if (sp == index->capa) sp = k;
     318    }
     319    else if (ht_hash_equal(mrb, t, key, key2)) {
     320      index->table[k]->val = val;
     321      return;
     322    }
     323    k = (k+(++step)) & mask;
     324  }
     325  if (sp < index->capa) {
     326    k = sp;
     327  }
     328
     329  /* put the value at the last */
     330  seg = t->lastseg;
     331  if (t->last_len < seg->size) {
     332    index->table[k] = &seg->e[t->last_len++];
     333  }
     334  else {                        /* append a new segment */
     335    seg->next = segment_alloc(mrb, seg);
     336    seg = seg->next;
     337    seg->next = NULL;
     338    t->lastseg = seg;
     339    t->last_len = 1;
     340    index->table[k] = &seg->e[0];
     341  }
     342  index->table[k]->key = key;
     343  index->table[k]->val = val;
     344  index->size++;
     345  t->size++;
     346}
     347
     348/* Set the value for the key in the hash table. */
     349static void
     350ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
     351{
     352  segment *seg;
     353  mrb_int i, deleted = 0;
     354
     355  if (t == NULL) return;
     356  if (t->index) {
     357    ht_index_put(mrb, t, key, val);
     358    return;
     359  }
     360  seg = t->rootseg;
     361  while (seg) {
     362    for (i=0; i<seg->size; i++) {
     363      mrb_value k = seg->e[i].key;
     364      /* Found room in last segment after last_len */
     365      if (!seg->next && i >= t->last_len) {
     366        seg->e[i].key = key;
     367        seg->e[i].val = val;
     368        t->last_len = i+1;
     369        t->size++;
     370        return;
     371      }
     372      if (mrb_undef_p(k)) {
     373        deleted++;
     374        continue;
     375      }
     376      if (ht_hash_equal(mrb, t, k, key)) {
     377        seg->e[i].val = val;
     378        return;
     379      }
     380    }
     381    seg = seg->next;
     382  }
     383  /* Not found */
     384
     385  /* Compact if last segment has room */
     386  if (deleted > 0 && deleted > MRB_HT_INIT_SIZE) {
     387    ht_compact(mrb, t);
     388  }
     389  t->size++;
     390
     391  /* check if thre's room after compaction */
     392  if (t->lastseg && t->last_len < t->lastseg->size) {
     393    seg = t->lastseg;
     394    i = t->last_len;
     395  }
     396  else {
     397    /* append new segment */
     398    seg = segment_alloc(mrb, t->lastseg);
     399    i = 0;
     400    if (t->rootseg == NULL) {
     401      t->rootseg = seg;
     402    }
     403    else {
     404      t->lastseg->next = seg;
     405    }
     406    t->lastseg = seg;
     407  }
     408  seg->e[i].key = key;
     409  seg->e[i].val = val;
     410  t->last_len = i+1;
     411  if (t->index == NULL && t->size > MRB_HT_INIT_SIZE*4) {
     412    ht_index(mrb, t);
     413  }
     414}
     415
     416/* Get a value for a key from the indexed table. */
     417static mrb_bool
     418ht_index_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
     419{
     420  segindex *index = t->index;
     421  size_t mask = HT_MASK(index);
     422  size_t k = ht_hash_func(mrb, t, key) & mask;
     423  size_t step = 0;
     424
     425  while (index->table[k]) {
     426    mrb_value key2 = index->table[k]->key;
     427    if (!mrb_undef_p(key2) && ht_hash_equal(mrb, t, key, key2)) {
     428      if (vp) *vp = index->table[k]->val;
     429      return TRUE;
     430    }
     431    k = (k+(++step)) & mask;
     432  }
     433  return FALSE;
     434}
     435
     436/* Get a value for a key from the hash table. */
     437static mrb_bool
     438ht_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
     439{
     440  segment *seg;
     441  mrb_int i;
     442
     443  if (t == NULL) return FALSE;
     444  if (t->index) {
     445    return ht_index_get(mrb, t, key, vp);
     446  }
     447
     448  seg = t->rootseg;
     449  while (seg) {
     450    for (i=0; i<seg->size; i++) {
     451      mrb_value k = seg->e[i].key;
     452
     453      if (!seg->next && i >= t->last_len) {
     454        return FALSE;
     455      }
     456      if (mrb_undef_p(k)) continue;
     457      if (ht_hash_equal(mrb, t, k, key)) {
     458        if (vp) *vp = seg->e[i].val;
     459        return TRUE;
     460      }
     461    }
     462    seg = seg->next;
     463  }
     464  return FALSE;
     465}
     466
     467/* Deletes the value for the symbol from the hash table. */
     468/* Deletion is done by overwriting keys by `undef`. */
     469static mrb_bool
     470ht_del(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
     471{
     472  segment *seg;
     473  mrb_int i;
     474
     475  if (t == NULL) return FALSE;
     476  seg = t->rootseg;
     477  while (seg) {
     478    for (i=0; i<seg->size; i++) {
     479      mrb_value key2;
     480
     481      if (!seg->next && i >= t->last_len) {
     482        /* not found */
     483        return FALSE;
     484      }
     485      key2 = seg->e[i].key;
     486      if (!mrb_undef_p(key2) && ht_hash_equal(mrb, t, key, key2)) {
     487        if (vp) *vp = seg->e[i].val;
     488        seg->e[i].key = mrb_undef_value();
     489        t->size--;
     490        return TRUE;
     491      }
     492    }
     493    seg = seg->next;
     494  }
     495  return FALSE;
     496}
     497
     498/* Iterates over the hash table. */
     499static void
     500ht_foreach(mrb_state *mrb, htable *t, mrb_hash_foreach_func *func, void *p)
     501{
     502  segment *seg;
     503  mrb_int i;
     504
     505  if (t == NULL) return;
     506  seg = t->rootseg;
     507  while (seg) {
     508    for (i=0; i<seg->size; i++) {
     509      /* no value in last segment after last_len */
     510      if (!seg->next && i >= t->last_len) {
     511        return;
     512      }
     513      if (mrb_undef_p(seg->e[i].key)) continue;
     514      if ((*func)(mrb, seg->e[i].key, seg->e[i].val, p) != 0)
     515        return;
     516    }
     517    seg = seg->next;
     518  }
     519}
     520
     521/* Iterates over the hash table. */
     522MRB_API void
     523mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p)
     524{
     525  ht_foreach(mrb, hash->ht, func, p);
     526}
     527
     528/* Copy the hash table. */
     529static htable*
     530ht_copy(mrb_state *mrb, htable *t)
     531{
     532  segment *seg;
     533  htable *t2;
     534  mrb_int i;
     535
     536  seg = t->rootseg;
     537  t2 = ht_new(mrb);
     538  if (t->size == 0) return t2;
     539
     540  while (seg) {
     541    for (i=0; i<seg->size; i++) {
     542      mrb_value key = seg->e[i].key;
     543      mrb_value val = seg->e[i].val;
     544
     545      if ((seg->next == NULL) && (i >= t->last_len)) {
     546        return t2;
     547      }
     548      if (mrb_undef_p(key)) continue; /* skip deleted key */
     549      ht_put(mrb, t2, key, val);
     550    }
     551    seg = seg->next;
     552  }
     553  return t2;
     554}
     555
     556/* Free memory of the hash table. */
     557static void
     558ht_free(mrb_state *mrb, htable *t)
     559{
     560  segment *seg;
     561
     562  if (!t) return;
     563  seg = t->rootseg;
     564  while (seg) {
     565    segment *p = seg;
     566    seg = seg->next;
     567    mrb_free(mrb, p);
     568  }
     569  if (t->index) mrb_free(mrb, t->index);
     570  mrb_free(mrb, t);
     571}
    95572
    96573static void mrb_hash_modify(mrb_state *mrb, mrb_value hash);
    97574
    98575static inline mrb_value
    99 mrb_hash_ht_key(mrb_state *mrb, mrb_value key)
    100 {
    101   if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) {
     576ht_key(mrb_state *mrb, mrb_value key)
     577{
     578  if (mrb_string_p(key) && !mrb_frozen_p(mrb_str_ptr(key))) {
    102579    key = mrb_str_dup(mrb, key);
    103580    MRB_SET_FROZEN_FLAG(mrb_str_ptr(key));
     
    106583}
    107584
    108 #define KEY(key) mrb_hash_ht_key(mrb, key)
     585#define KEY(key) ht_key(mrb, key)
     586
     587static int
     588hash_mark_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
     589{
     590  mrb_gc_mark_value(mrb, key);
     591  mrb_gc_mark_value(mrb, val);
     592  return 0;
     593}
    109594
    110595void
    111596mrb_gc_mark_hash(mrb_state *mrb, struct RHash *hash)
    112597{
    113   khiter_t k;
    114   khash_t(ht) *h = hash->ht;
    115 
    116   if (!h) return;
    117   for (k = kh_begin(h); k != kh_end(h); k++) {
    118     if (kh_exist(h, k)) {
    119       mrb_value key = kh_key(h, k);
    120       mrb_value val = kh_value(h, k).v;
    121 
    122       mrb_gc_mark_value(mrb, key);
    123       mrb_gc_mark_value(mrb, val);
    124     }
    125   }
     598  ht_foreach(mrb, hash->ht, hash_mark_i, NULL);
    126599}
    127600
     
    130603{
    131604  if (!hash->ht) return 0;
    132   return kh_size(hash->ht)*2;
     605  return hash->ht->size*2;
    133606}
    134607
     
    136609mrb_gc_free_hash(mrb_state *mrb, struct RHash *hash)
    137610{
    138   if (hash->ht) kh_destroy(ht, mrb, hash->ht);
    139 }
    140 
     611  ht_free(mrb, hash->ht);
     612}
     613
     614MRB_API mrb_value
     615mrb_hash_new(mrb_state *mrb)
     616{
     617  struct RHash *h;
     618
     619  h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
     620  h->ht = 0;
     621  h->iv = 0;
     622  return mrb_obj_value(h);
     623}
    141624
    142625MRB_API mrb_value
     
    146629
    147630  h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
    148   h->ht = kh_init(ht, mrb);
    149   if (capa > 0) {
    150     kh_resize(ht, mrb, h->ht, capa);
    151   }
     631  /* preallocate hash table */
     632  h->ht = ht_new(mrb);
     633  /* capacity ignored */
    152634  h->iv = 0;
    153635  return mrb_obj_value(h);
    154636}
    155637
    156 MRB_API mrb_value
    157 mrb_hash_new(mrb_state *mrb)
    158 {
    159   return mrb_hash_new_capa(mrb, 0);
    160 }
    161 
    162638static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash);
    163639static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key);
    164640
     641static mrb_value
     642mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
     643{
     644  mrb_value orig;
     645  struct RHash* copy;
     646  htable *orig_h;
     647  mrb_value ifnone, vret;
     648
     649  mrb_get_args(mrb, "o", &orig);
     650  if (mrb_obj_equal(mrb, self, orig)) return self;
     651  if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) {
     652      mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object");
     653  }
     654
     655  orig_h = RHASH_TBL(self);
     656  copy = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
     657  copy->ht = ht_copy(mrb, orig_h);
     658
     659  if (MRB_RHASH_DEFAULT_P(self)) {
     660    copy->flags |= MRB_HASH_DEFAULT;
     661  }
     662  if (MRB_RHASH_PROCDEFAULT_P(self)) {
     663    copy->flags |= MRB_HASH_PROC_DEFAULT;
     664  }
     665  vret = mrb_obj_value(copy);
     666  ifnone = RHASH_IFNONE(self);
     667  if (!mrb_nil_p(ifnone)) {
     668      mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);
     669  }
     670  return vret;
     671}
     672
     673static int
     674check_kdict_i(mrb_state *mrb, mrb_value key, mrb_value val, void *data)
     675{
     676  if (!mrb_symbol_p(key)) {
     677    mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword argument hash with non symbol keys");
     678  }
     679  return 0;
     680}
     681
     682void
     683mrb_hash_check_kdict(mrb_state *mrb, mrb_value self)
     684{
     685  htable *t;
     686
     687  t = RHASH_TBL(self);
     688  if (!t || t->size == 0) return;
     689  ht_foreach(mrb, t, check_kdict_i, NULL);
     690}
     691
     692MRB_API mrb_value
     693mrb_hash_dup(mrb_state *mrb, mrb_value self)
     694{
     695  struct RHash* copy;
     696  htable *orig_h;
     697
     698  orig_h = RHASH_TBL(self);
     699  copy = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
     700  copy->ht = orig_h ? ht_copy(mrb, orig_h) : NULL;
     701  return mrb_obj_value(copy);
     702}
     703
    165704MRB_API mrb_value
    166705mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
    167706{
    168   khash_t(ht) *h = RHASH_TBL(hash);
    169   khiter_t k;
     707  mrb_value val;
    170708  mrb_sym mid;
    171709
    172   if (h) {
    173     k = kh_get(ht, mrb, h, key);
    174     if (k != kh_end(h))
    175       return kh_value(h, k).v;
     710  if (ht_get(mrb, RHASH_TBL(hash), key, &val)) {
     711    return val;
    176712  }
    177713
     
    187723mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
    188724{
    189   khash_t(ht) *h = RHASH_TBL(hash);
    190   khiter_t k;
    191 
    192   if (h) {
    193     k = kh_get(ht, mrb, h, key);
    194     if (k != kh_end(h))
    195       return kh_value(h, k).v;
    196   }
    197 
     725  mrb_value val;
     726
     727  if (ht_get(mrb, RHASH_TBL(hash), key, &val)) {
     728    return val;
     729  }
    198730  /* not found */
    199731  return def;
     
    203735mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
    204736{
    205   khash_t(ht) *h;
    206   khiter_t k;
    207   int r;
    208 
    209737  mrb_hash_modify(mrb, hash);
    210   h = RHASH_TBL(hash);
    211 
    212   if (!h) h = RHASH_TBL(hash) = kh_init(ht, mrb);
    213   k = kh_put2(ht, mrb, h, key, &r);
    214   kh_value(h, k).v = val;
    215 
    216   if (r != 0) {
    217     /* expand */
    218     int ai = mrb_gc_arena_save(mrb);
    219     key = kh_key(h, k) = KEY(key);
    220     mrb_gc_arena_restore(mrb, ai);
    221     kh_value(h, k).n = kh_size(h)-1;
    222   }
    223 
     738
     739  key = KEY(key);
     740  ht_put(mrb, RHASH_TBL(hash), key, val);
    224741  mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), key);
    225742  mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), val);
     
    227744}
    228745
    229 static mrb_value
    230 mrb_hash_dup(mrb_state *mrb, mrb_value hash)
    231 {
    232   struct RHash* ret;
    233   khash_t(ht) *h, *ret_h;
    234   khiter_t k, ret_k;
    235   mrb_value ifnone, vret;
    236 
    237   h = RHASH_TBL(hash);
    238   ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
    239   ret->ht = kh_init(ht, mrb);
    240 
    241   if (h && kh_size(h) > 0) {
    242     ret_h = ret->ht;
    243 
    244     for (k = kh_begin(h); k != kh_end(h); k++) {
    245       if (kh_exist(h, k)) {
    246         int ai = mrb_gc_arena_save(mrb);
    247         ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k)));
    248         mrb_gc_arena_restore(mrb, ai);
    249         kh_val(ret_h, ret_k).v = kh_val(h, k).v;
    250         kh_val(ret_h, ret_k).n = kh_size(ret_h)-1;
    251       }
    252     }
    253   }
    254 
    255   if (MRB_RHASH_DEFAULT_P(hash)) {
    256     ret->flags |= MRB_HASH_DEFAULT;
    257   }
    258   if (MRB_RHASH_PROCDEFAULT_P(hash)) {
    259     ret->flags |= MRB_HASH_PROC_DEFAULT;
    260   }
    261   vret = mrb_obj_value(ret);
    262   ifnone = RHASH_IFNONE(hash);
    263   if (!mrb_nil_p(ifnone)) {
    264       mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);
    265   }
    266   return vret;
    267 }
    268 
    269 MRB_API mrb_value
    270 mrb_check_hash_type(mrb_state *mrb, mrb_value hash)
    271 {
    272   return mrb_check_convert_type(mrb, hash, MRB_TT_HASH, "Hash", "to_hash");
    273 }
    274 
    275 MRB_API khash_t(ht)*
    276 mrb_hash_tbl(mrb_state *mrb, mrb_value hash)
    277 {
    278   khash_t(ht) *h = RHASH_TBL(hash);
    279 
    280   if (!h) {
    281     return RHASH_TBL(hash) = kh_init(ht, mrb);
    282   }
    283   return h;
    284 }
    285 
    286746static void
    287747mrb_hash_modify(mrb_state *mrb, mrb_value hash)
    288748{
    289   if (MRB_FROZEN_P(mrb_hash_ptr(hash))) {
    290     mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash");
    291   }
    292   mrb_hash_tbl(mrb, hash);
     749  mrb_check_frozen(mrb, mrb_hash_ptr(hash));
     750  if (!RHASH_TBL(hash)) {
     751    RHASH_TBL(hash) = ht_new(mrb);
     752  }
    293753}
    294754
     
    340800  if (!mrb_nil_p(block)) {
    341801    if (ifnone_p) {
    342       mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
     802      mrb_argnum_error(mrb, 1, 0, 0);
    343803    }
    344804    RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
     
    530990mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
    531991{
    532   khash_t(ht) *h = RHASH_TBL(hash);
    533   khiter_t k;
    534   mrb_value delVal;
    535   mrb_int n;
    536 
    537   if (h) {
    538     k = kh_get(ht, mrb, h, key);
    539     if (k != kh_end(h)) {
    540       delVal = kh_value(h, k).v;
    541       n = kh_value(h, k).n;
    542       kh_del(ht, mrb, h, k);
    543       for (k = kh_begin(h); k != kh_end(h); k++) {
    544         if (!kh_exist(h, k)) continue;
    545         if (kh_value(h, k).n > n) kh_value(h, k).n--;
    546       }
    547       return delVal;
    548     }
     992  htable *t = RHASH_TBL(hash);
     993  mrb_value del_val;
     994
     995  if (ht_del(mrb, t, key, &del_val)) {
     996    return del_val;
    549997  }
    550998
     
    5531001}
    5541002
    555 /* 15.2.13.4.8  */
    556 /*
    557  *  call-seq:
    558  *     hsh.delete(key)                   -> value
    559  *     hsh.delete(key) {| key | block }  -> value
    560  *
    561  *  Deletes and returns a key-value pair from <i>hsh</i> whose key is
    562  *  equal to <i>key</i>. If the key is not found, returns the
    563  *  <em>default value</em>. If the optional code block is given and the
    564  *  key is not found, pass in the key and return the result of
    565  *  <i>block</i>.
    566  *
    567  *      h = { "a" => 100, "b" => 200 }
    568  *      h.delete("a")                              #=> 100
    569  *      h.delete("z")                              #=> nil
    570  *      h.delete("z") { |el| "#{el} not found" }   #=> "z not found"
    571  *
    572  */
    5731003static mrb_value
    5741004mrb_hash_delete(mrb_state *mrb, mrb_value self)
     
    5811011}
    5821012
     1013/* find first element in the hash table, and remove it. */
     1014static void
     1015ht_shift(mrb_state *mrb, htable *t, mrb_value *kp, mrb_value *vp)
     1016{
     1017  segment *seg = t->rootseg;
     1018  mrb_int i;
     1019
     1020  while (seg) {
     1021    for (i=0; i<seg->size; i++) {
     1022      mrb_value key;
     1023
     1024      if (!seg->next && i >= t->last_len) {
     1025        return;
     1026      }
     1027      key = seg->e[i].key;
     1028      if (mrb_undef_p(key)) continue;
     1029      *kp = key;
     1030      *vp = seg->e[i].val;
     1031      /* delete element */
     1032      seg->e[i].key = mrb_undef_value();
     1033      t->size--;
     1034      return;
     1035    }
     1036    seg = seg->next;
     1037  }
     1038}
     1039
    5831040/* 15.2.13.4.24 */
    5841041/*
     
    5981055mrb_hash_shift(mrb_state *mrb, mrb_value hash)
    5991056{
    600   khash_t(ht) *h = RHASH_TBL(hash);
    601   khiter_t k;
    602   mrb_value delKey, delVal;
     1057  htable *t = RHASH_TBL(hash);
    6031058
    6041059  mrb_hash_modify(mrb, hash);
    605   if (h && kh_size(h) > 0) {
    606     for (k = kh_begin(h); k != kh_end(h); k++) {
    607       if (!kh_exist(h, k)) continue;
    608 
    609       delKey = kh_key(h, k);
    610       mrb_gc_protect(mrb, delKey);
    611       delVal = mrb_hash_delete_key(mrb, hash, delKey);
    612       mrb_gc_protect(mrb, delVal);
    613 
    614       return mrb_assoc_new(mrb, delKey, delVal);
    615     }
     1060  if (t && t->size > 0) {
     1061    mrb_value del_key, del_val;
     1062
     1063    ht_shift(mrb, t, &del_key, &del_val);
     1064    mrb_gc_protect(mrb, del_key);
     1065    mrb_gc_protect(mrb, del_val);
     1066    return mrb_assoc_new(mrb, del_key, del_val);
    6161067  }
    6171068
     
    6421093mrb_hash_clear(mrb_state *mrb, mrb_value hash)
    6431094{
    644   khash_t(ht) *h = RHASH_TBL(hash);
     1095  htable *t = RHASH_TBL(hash);
    6451096
    6461097  mrb_hash_modify(mrb, hash);
    647   if (h) kh_clear(ht, mrb, h);
     1098  if (t) {
     1099    ht_free(mrb, t);
     1100    RHASH_TBL(hash) = NULL;
     1101  }
    6481102  return hash;
    6491103}
     
    6781132}
    6791133
     1134MRB_API mrb_int
     1135mrb_hash_size(mrb_state *mrb, mrb_value hash)
     1136{
     1137  htable *t = RHASH_TBL(hash);
     1138
     1139  if (!t) return 0;
     1140  return t->size;
     1141}
     1142
    6801143/* 15.2.13.4.20 */
    6811144/* 15.2.13.4.25 */
     
    6951158mrb_hash_size_m(mrb_state *mrb, mrb_value self)
    6961159{
    697   khash_t(ht) *h = RHASH_TBL(self);
    698 
    699   if (!h) return mrb_fixnum_value(0);
    700   return mrb_fixnum_value(kh_size(h));
     1160  mrb_int size = mrb_hash_size(mrb, self);
     1161  return mrb_fixnum_value(size);
     1162}
     1163
     1164MRB_API mrb_bool
     1165mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
     1166{
     1167  htable *t = RHASH_TBL(self);
     1168
     1169  if (!t) return TRUE;
     1170  return t->size == 0;
    7011171}
    7021172
     
    7111181 *
    7121182 */
    713 MRB_API mrb_value
    714 mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
    715 {
    716   khash_t(ht) *h = RHASH_TBL(self);
    717 
    718   if (h) return mrb_bool_value(kh_size(h) == 0);
    719   return mrb_true_value();
    720 }
    721 
    722 /* 15.2.13.4.29 (x)*/
    723 /*
    724  * call-seq:
    725  *    hsh.to_hash   => hsh
    726  *
    727  * Returns +self+.
    728  */
    729 
    730 static mrb_value
    731 mrb_hash_to_hash(mrb_state *mrb, mrb_value hash)
    732 {
    733   return hash;
     1183static mrb_value
     1184mrb_hash_empty_m(mrb_state *mrb, mrb_value self)
     1185{
     1186  return mrb_bool_value(mrb_hash_empty_p(mrb, self));
     1187}
     1188
     1189static int
     1190hash_keys_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
     1191{
     1192  mrb_ary_push(mrb, *(mrb_value*)p, key);
     1193  return 0;
    7341194}
    7351195
     
    7501210mrb_hash_keys(mrb_state *mrb, mrb_value hash)
    7511211{
    752   khash_t(ht) *h = RHASH_TBL(hash);
    753   khiter_t k;
    754   mrb_int end;
     1212  htable *t = RHASH_TBL(hash);
     1213  mrb_int size;
    7551214  mrb_value ary;
    756   mrb_value *p;
    757 
    758   if (!h || kh_size(h) == 0) return mrb_ary_new(mrb);
    759   ary = mrb_ary_new_capa(mrb, kh_size(h));
    760   end = kh_size(h)-1;
    761   mrb_ary_set(mrb, ary, end, mrb_nil_value());
    762   p = mrb_ary_ptr(ary)->ptr;
    763   for (k = kh_begin(h); k != kh_end(h); k++) {
    764     if (kh_exist(h, k)) {
    765       mrb_value kv = kh_key(h, k);
    766       mrb_hash_value hv = kh_value(h, k);
    767 
    768       if (hv.n <= end) {
    769         p[hv.n] = kv;
    770       }
    771       else {
    772         p[end] = kv;
    773       }
    774     }
    775   }
     1215
     1216  if (!t || (size = t->size) == 0)
     1217    return mrb_ary_new(mrb);
     1218  ary = mrb_ary_new_capa(mrb, size);
     1219  ht_foreach(mrb, t, hash_keys_i, (void*)&ary);
    7761220  return ary;
     1221}
     1222
     1223static int
     1224hash_vals_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
     1225{
     1226  mrb_ary_push(mrb, *(mrb_value*)p, val);
     1227  return 0;
    7771228}
    7781229
     
    7931244mrb_hash_values(mrb_state *mrb, mrb_value hash)
    7941245{
    795   khash_t(ht) *h = RHASH_TBL(hash);
    796   khiter_t k;
     1246  htable *t = RHASH_TBL(hash);
     1247  mrb_int size;
    7971248  mrb_value ary;
    7981249
    799   if (!h) return mrb_ary_new(mrb);
    800   ary = mrb_ary_new_capa(mrb, kh_size(h));
    801   for (k = kh_begin(h); k != kh_end(h); k++) {
    802     if (kh_exist(h, k)) {
    803       mrb_hash_value hv = kh_value(h, k);
    804 
    805       mrb_ary_set(mrb, ary, hv.n, hv.v);
    806     }
    807   }
     1250  if (!t || (size = t->size) == 0)
     1251    return mrb_ary_new(mrb);
     1252  ary = mrb_ary_new_capa(mrb, size);
     1253  ht_foreach(mrb, t, hash_vals_i, (void*)&ary);
    8081254  return ary;
    8091255}
     
    8281274 */
    8291275
     1276MRB_API mrb_bool
     1277mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key)
     1278{
     1279  htable *t;
     1280
     1281  t = RHASH_TBL(hash);
     1282  if (ht_get(mrb, t, key, NULL)) {
     1283    return TRUE;
     1284  }
     1285  return FALSE;
     1286}
     1287
    8301288static mrb_value
    8311289mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
    8321290{
    8331291  mrb_value key;
    834   khash_t(ht) *h;
    835   khiter_t k;
     1292  mrb_bool key_p;
    8361293
    8371294  mrb_get_args(mrb, "o", &key);
    838 
    839   h = RHASH_TBL(hash);
    840   if (h) {
    841     k = kh_get(ht, mrb, h, key);
    842     return mrb_bool_value(k != kh_end(h));
    843   }
    844   return mrb_false_value();
     1295  key_p = mrb_hash_key_p(mrb, hash, key);
     1296  return mrb_bool_value(key_p);
     1297}
     1298
     1299struct has_v_arg {
     1300  mrb_bool found;
     1301  mrb_value val;
     1302};
     1303
     1304static int
     1305hash_has_value_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
     1306{
     1307  struct has_v_arg *arg = (struct has_v_arg*)p;
     1308 
     1309  if (mrb_equal(mrb, arg->val, val)) {
     1310    arg->found = TRUE;
     1311    return 1;
     1312  }
     1313  return 0;
    8451314}
    8461315
     
    8641333{
    8651334  mrb_value val;
    866   khash_t(ht) *h;
    867   khiter_t k;
    868 
     1335  struct has_v_arg arg;
     1336 
    8691337  mrb_get_args(mrb, "o", &val);
    870   h = RHASH_TBL(hash);
    871 
    872   if (h) {
    873     for (k = kh_begin(h); k != kh_end(h); k++) {
    874       if (!kh_exist(h, k)) continue;
    875 
    876       if (mrb_equal(mrb, kh_value(h, k).v, val)) {
    877         return mrb_true_value();
    878       }
    879     }
    880   }
    881   return mrb_false_value();
     1338  arg.found = FALSE;
     1339  arg.val = val;
     1340  ht_foreach(mrb, RHASH_TBL(hash), hash_has_value_i, &arg);
     1341  return mrb_bool_value(arg.found);
     1342}
     1343
     1344static int
     1345merge_i(mrb_state *mrb, mrb_value key, mrb_value val, void *data)
     1346{
     1347  htable *h1 = (htable*)data;
     1348
     1349  ht_put(mrb, h1, key, val);
     1350  return 0;
     1351}
     1352
     1353MRB_API void
     1354mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2)
     1355{
     1356  htable *h1, *h2;
     1357
     1358  mrb_hash_modify(mrb, hash1);
     1359  hash2 = mrb_ensure_hash_type(mrb, hash2);
     1360  h1 = RHASH_TBL(hash1);
     1361  h2 = RHASH_TBL(hash2);
     1362
     1363  if (!h2) return;
     1364  if (!h1) {
     1365    RHASH_TBL(hash1) = ht_copy(mrb, h2);
     1366    return;
     1367  }
     1368  ht_foreach(mrb, h2, merge_i, h1);
     1369  mrb_write_barrier(mrb, (struct RBasic*)RHASH(hash1));
     1370  return;
     1371}
     1372
     1373/*
     1374 *  call-seq:
     1375 *    hsh.rehash -> hsh
     1376 *
     1377 *  Rebuilds the hash based on the current hash values for each key. If
     1378 *  values of key objects have changed since they were inserted, this
     1379 *  method will reindex <i>hsh</i>.
     1380 *
     1381 *     keys = (1..17).map{|n| [n]}
     1382 *     k = keys[0]
     1383 *     h = {}
     1384 *     keys.each{|key| h[key] = key[0]}
     1385 *     h     #=> { [1]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7,
     1386 *                 [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14,
     1387 *                [15]=>15,[16]=>16,[17]=>17}
     1388 *     h[k]  #=> 1
     1389 *     k[0] = keys.size + 1
     1390 *     h     #=> {[18]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7,
     1391 *                 [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14,
     1392 *                [15]=>15,[16]=>16,[17]=>17}
     1393 *     h[k]  #=> nil
     1394 *     h.rehash
     1395 *     h[k]  #=> 1
     1396 */
     1397static mrb_value
     1398mrb_hash_rehash(mrb_state *mrb, mrb_value self)
     1399{
     1400  ht_compact(mrb, RHASH_TBL(self));
     1401  return self;
    8821402}
    8831403
     
    8901410  MRB_SET_INSTANCE_TT(h, MRB_TT_HASH);
    8911411
     1412  mrb_define_method(mrb, h, "initialize_copy", mrb_hash_init_copy,   MRB_ARGS_REQ(1));
    8921413  mrb_define_method(mrb, h, "[]",              mrb_hash_aget,        MRB_ARGS_REQ(1)); /* 15.2.13.4.2  */
    8931414  mrb_define_method(mrb, h, "[]=",             mrb_hash_aset,        MRB_ARGS_REQ(2)); /* 15.2.13.4.3  */
    8941415  mrb_define_method(mrb, h, "clear",           mrb_hash_clear,       MRB_ARGS_NONE()); /* 15.2.13.4.4  */
    895   mrb_define_method(mrb, h, "default",         mrb_hash_default,     MRB_ARGS_ANY());  /* 15.2.13.4.5  */
     1416  mrb_define_method(mrb, h, "default",         mrb_hash_default,     MRB_ARGS_OPT(1));  /* 15.2.13.4.5  */
    8961417  mrb_define_method(mrb, h, "default=",        mrb_hash_set_default, MRB_ARGS_REQ(1)); /* 15.2.13.4.6  */
    8971418  mrb_define_method(mrb, h, "default_proc",    mrb_hash_default_proc,MRB_ARGS_NONE()); /* 15.2.13.4.7  */
    8981419  mrb_define_method(mrb, h, "default_proc=",   mrb_hash_set_default_proc,MRB_ARGS_REQ(1)); /* 15.2.13.4.7  */
    8991420  mrb_define_method(mrb, h, "__delete",        mrb_hash_delete,      MRB_ARGS_REQ(1)); /* core of 15.2.13.4.8  */
    900   mrb_define_method(mrb, h, "empty?",          mrb_hash_empty_p,     MRB_ARGS_NONE()); /* 15.2.13.4.12 */
     1421  mrb_define_method(mrb, h, "empty?",          mrb_hash_empty_m,     MRB_ARGS_NONE()); /* 15.2.13.4.12 */
    9011422  mrb_define_method(mrb, h, "has_key?",        mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.13 */
    9021423  mrb_define_method(mrb, h, "has_value?",      mrb_hash_has_value,   MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */
    9031424  mrb_define_method(mrb, h, "include?",        mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */
    904   mrb_define_method(mrb, h, "initialize",      mrb_hash_init,        MRB_ARGS_OPT(1)); /* 15.2.13.4.16 */
     1425  mrb_define_method(mrb, h, "initialize",      mrb_hash_init,        MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.2.13.4.16 */
    9051426  mrb_define_method(mrb, h, "key?",            mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */
    9061427  mrb_define_method(mrb, h, "keys",            mrb_hash_keys,        MRB_ARGS_NONE()); /* 15.2.13.4.19 */
     
    9081429  mrb_define_method(mrb, h, "member?",         mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.21 */
    9091430  mrb_define_method(mrb, h, "shift",           mrb_hash_shift,       MRB_ARGS_NONE()); /* 15.2.13.4.24 */
    910   mrb_define_method(mrb, h, "dup",             mrb_hash_dup,         MRB_ARGS_NONE());
    9111431  mrb_define_method(mrb, h, "size",            mrb_hash_size_m,      MRB_ARGS_NONE()); /* 15.2.13.4.25 */
    9121432  mrb_define_method(mrb, h, "store",           mrb_hash_aset,        MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */
    9131433  mrb_define_method(mrb, h, "value?",          mrb_hash_has_value,   MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */
    9141434  mrb_define_method(mrb, h, "values",          mrb_hash_values,      MRB_ARGS_NONE()); /* 15.2.13.4.28 */
    915 
    916   mrb_define_method(mrb, h, "to_hash",         mrb_hash_to_hash,     MRB_ARGS_NONE()); /* 15.2.13.4.29 (x)*/
    917 }
     1435  mrb_define_method(mrb, h, "rehash",          mrb_hash_rehash,      MRB_ARGS_NONE());
     1436}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/kernel.c

    r331 r439  
    1515#include <mruby/istruct.h>
    1616
    17 typedef enum {
    18   NOEX_PUBLIC    = 0x00,
    19   NOEX_NOSUPER   = 0x01,
    20   NOEX_PRIVATE   = 0x02,
    21   NOEX_PROTECTED = 0x04,
    22   NOEX_MASK      = 0x06,
    23   NOEX_BASIC     = 0x08,
    24   NOEX_UNDEF     = NOEX_NOSUPER,
    25   NOEX_MODFUNC   = 0x12,
    26   NOEX_SUPER     = 0x20,
    27   NOEX_VCALL     = 0x40,
    28   NOEX_RESPONDS  = 0x80
    29 } mrb_method_flag_t;
    30 
    3117MRB_API mrb_bool
    3218mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func)
    3319{
    34   struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid);
    35   if (MRB_PROC_CFUNC_P(me) && (me->body.func == func))
     20  struct RClass *c = mrb_class(mrb, obj);
     21  mrb_method_t m = mrb_method_search_vm(mrb, &c, mid);
     22  struct RProc *p;
     23
     24  if (MRB_METHOD_UNDEF_P(m)) return FALSE;
     25  if (MRB_METHOD_FUNC_P(m))
     26    return MRB_METHOD_FUNC(m) == func;
     27  p = MRB_METHOD_PROC(m);
     28  if (MRB_PROC_CFUNC_P(p) && (MRB_PROC_CFUNC(p) == func))
    3629    return TRUE;
    3730  return FALSE;
     
    6154mrb_obj_inspect(mrb_state *mrb, mrb_value obj)
    6255{
    63   if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) {
     56  if (mrb_object_p(obj) && mrb_obj_basic_to_s_p(mrb, obj)) {
    6457    return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj));
    6558  }
     
    135128mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
    136129{
    137   mrb_callinfo *ci = mrb->c->ci;
     130  mrb_callinfo *ci = &mrb->c->ci[-1];
     131  mrb_callinfo *cibase = mrb->c->cibase;
    138132  mrb_value *bp;
    139 
    140   bp = ci->stackent + 1;
    141   ci--;
    142   if (ci <= mrb->c->cibase) {
     133  struct RProc *p;
     134
     135  if (ci <= cibase) {
     136    /* toplevel does not have block */
    143137    return mrb_false_value();
    144138  }
    145   /* block_given? called within block; check upper scope */
    146   if (ci->proc->env) {
    147     struct REnv *e = ci->proc->env;
    148 
    149     while (e->c) {
    150       e = (struct REnv*)e->c;
    151     }
     139  p = ci->proc;
     140  /* search method/class/module proc */
     141  while (p) {
     142    if (MRB_PROC_SCOPE_P(p)) break;
     143    p = p->upper;
     144  }
     145  if (p == NULL) return mrb_false_value();
     146  /* search ci corresponding to proc */
     147  while (cibase < ci) {
     148    if (ci->proc == p) break;
     149    ci--;
     150  }
     151  if (ci == cibase) {
     152    return mrb_false_value();
     153  }
     154  else if (ci->env) {
     155    struct REnv *e = ci->env;
     156    int bidx;
     157
    152158    /* top-level does not have block slot (always false) */
    153159    if (e->stack == mrb->c->stbase)
    154160      return mrb_false_value();
    155     if (e->stack && e->cioff < 0) {
    156       /* use saved block arg position */
    157       bp = &e->stack[-e->cioff];
    158       ci = 0;                 /* no callinfo available */
     161    /* use saved block arg position */
     162    bidx = MRB_ENV_BIDX(e);
     163    /* bidx may be useless (e.g. define_method) */
     164    if (bidx >= MRB_ENV_STACK_LEN(e))
     165      return mrb_false_value();
     166    bp = &e->stack[bidx];
     167  }
     168  else {
     169    bp = ci[1].stackent+1;
     170    if (ci->argc >= 0) {
     171      bp += ci->argc;
    159172    }
    160173    else {
    161       ci = e->cxt.c->cibase + e->cioff;
    162       bp = ci[1].stackent + 1;
    163     }
    164   }
    165   if (ci && ci->argc > 0) {
    166     bp += ci->argc;
     174      bp++;
     175    }
    167176  }
    168177  if (mrb_nil_p(*bp))
     
    231240  /* if the origin is not the same as the class, then the origin and
    232241     the current class need to be copied */
    233   if (sc->flags & MRB_FLAG_IS_PREPENDED) {
     242  if (sc->flags & MRB_FL_CLASS_IS_PREPENDED) {
    234243    struct RClass *c0 = sc->super;
    235244    struct RClass *c1 = dc;
    236245
    237246    /* copy prepended iclasses */
    238     while (!(c0->flags & MRB_FLAG_IS_ORIGIN)) {
     247    while (!(c0->flags & MRB_FL_CLASS_IS_ORIGIN)) {
    239248      c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
    240249      c1 = c1->super;
     
    242251    }
    243252    c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
    244     c1->super->flags |= MRB_FLAG_IS_ORIGIN;
     253    c1->super->flags |= MRB_FL_CLASS_IS_ORIGIN;
    245254  }
    246255  if (sc->mt) {
     
    258267{
    259268  switch (mrb_type(obj)) {
     269    case MRB_TT_ICLASS:
     270      copy_class(mrb, dest, obj);
     271      return;
    260272    case MRB_TT_CLASS:
    261273    case MRB_TT_MODULE:
    262274      copy_class(mrb, dest, obj);
    263       /* fall through */
     275      mrb_iv_copy(mrb, dest, obj);
     276      mrb_iv_remove(mrb, dest, mrb_intern_lit(mrb, "__classname__"));
     277      break;
    264278    case MRB_TT_OBJECT:
    265279    case MRB_TT_SCLASS:
     
    312326
    313327  if (mrb_immediate_p(self)) {
    314     mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
    315   }
    316   if (mrb_type(self) == MRB_TT_SCLASS) {
     328    mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %v", self);
     329  }
     330  if (mrb_sclass_p(self)) {
    317331    mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
    318332  }
    319333  p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
    320334  p->c = mrb_singleton_class_clone(mrb, self);
     335  mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c);
    321336  clone = mrb_obj_value(p);
    322337  init_copy(mrb, clone, self);
     338  p->flags |= mrb_obj_ptr(self)->flags & MRB_FL_OBJ_IS_FROZEN;
    323339
    324340  return clone;
     
    351367
    352368  if (mrb_immediate_p(obj)) {
    353     mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
    354   }
    355   if (mrb_type(obj) == MRB_TT_SCLASS) {
     369    mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %v", obj);
     370  }
     371  if (mrb_sclass_p(obj)) {
    356372    mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
    357373  }
     
    369385
    370386  if (argc == 0) {
    371     mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)");
     387    mrb_argnum_error(mrb, argc, 1, -1);
    372388  }
    373389  for (i = 0; i < argc; i++) {
     
    411427  mrb_value *argv;
    412428  mrb_int argc;
    413   mrb_value args;
    414429
    415430  mrb_get_args(mrb, "*", &argv, &argc);
    416   args = mrb_ary_new_from_values(mrb, argc, argv);
    417   argv = (mrb_value*)RARRAY_PTR(args);
    418431  return mrb_obj_extend(mrb, argc, argv, self);
    419432}
    420433
    421 static mrb_value
     434MRB_API mrb_value
    422435mrb_obj_freeze(mrb_state *mrb, mrb_value self)
    423436{
    424   struct RBasic *b;
    425 
    426   switch (mrb_type(self)) {
    427     case MRB_TT_FALSE:
    428     case MRB_TT_TRUE:
    429     case MRB_TT_FIXNUM:
    430     case MRB_TT_SYMBOL:
    431     case MRB_TT_FLOAT:
    432       return self;
    433     default:
    434       break;
    435   }
    436 
    437   b = mrb_basic_ptr(self);
    438   if (!MRB_FROZEN_P(b)) {
    439     MRB_SET_FROZEN_FLAG(b);
     437  if (!mrb_immediate_p(self)) {
     438    struct RBasic *b = mrb_basic_ptr(self);
     439    if (!mrb_frozen_p(b)) {
     440      MRB_SET_FROZEN_FLAG(b);
     441      if (b->c->tt == MRB_TT_SCLASS) MRB_SET_FROZEN_FLAG(b->c);
     442    }
    440443  }
    441444  return self;
     
    445448mrb_obj_frozen(mrb_state *mrb, mrb_value self)
    446449{
    447   struct RBasic *b;
    448 
    449   switch (mrb_type(self)) {
    450     case MRB_TT_FALSE:
    451     case MRB_TT_TRUE:
    452     case MRB_TT_FIXNUM:
    453     case MRB_TT_SYMBOL:
    454     case MRB_TT_FLOAT:
    455       return mrb_true_value();
    456     default:
    457       break;
    458   }
    459 
    460   b = mrb_basic_ptr(self);
    461   if (!MRB_FROZEN_P(b)) {
    462     return mrb_false_value();
    463   }
    464   return mrb_true_value();
     450  return mrb_bool_value(mrb_immediate_p(self) || mrb_frozen_p(mrb_basic_ptr(self)));
    465451}
    466452
     
    476462 *  <code>Fixnum</code> will be truncated before being used.
    477463 */
    478 MRB_API mrb_value
     464static mrb_value
    479465mrb_obj_hash(mrb_state *mrb, mrb_value self)
    480466{
     
    520506
    521507  return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg)));
    522 }
    523 
    524 /* 15.3.1.3.20 */
    525 /*
    526  *  call-seq:
    527  *     obj.instance_variable_defined?(symbol)    -> true or false
    528  *
    529  *  Returns <code>true</code> if the given instance variable is
    530  *  defined in <i>obj</i>.
    531  *
    532  *     class Fred
    533  *       def initialize(p1, p2)
    534  *         @a, @b = p1, p2
    535  *       end
    536  *     end
    537  *     fred = Fred.new('cat', 99)
    538  *     fred.instance_variable_defined?(:@a)    #=> true
    539  *     fred.instance_variable_defined?("@b")   #=> true
    540  *     fred.instance_variable_defined?("@c")   #=> false
    541  */
    542 static mrb_value
    543 mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
    544 {
    545   mrb_sym sym;
    546 
    547   mrb_get_args(mrb, "n", &sym);
    548   mrb_iv_check(mrb, sym);
    549   return mrb_bool_value(mrb_iv_defined(mrb, self, sym));
    550 }
    551 
    552 /* 15.3.1.3.21 */
    553 /*
    554  *  call-seq:
    555  *     obj.instance_variable_get(symbol)    -> obj
    556  *
    557  *  Returns the value of the given instance variable, or nil if the
    558  *  instance variable is not set. The <code>@</code> part of the
    559  *  variable name should be included for regular instance
    560  *  variables. Throws a <code>NameError</code> exception if the
    561  *  supplied symbol is not valid as an instance variable name.
    562  *
    563  *     class Fred
    564  *       def initialize(p1, p2)
    565  *         @a, @b = p1, p2
    566  *       end
    567  *     end
    568  *     fred = Fred.new('cat', 99)
    569  *     fred.instance_variable_get(:@a)    #=> "cat"
    570  *     fred.instance_variable_get("@b")   #=> 99
    571  */
    572 static mrb_value
    573 mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
    574 {
    575   mrb_sym iv_name;
    576 
    577   mrb_get_args(mrb, "n", &iv_name);
    578   mrb_iv_check(mrb, iv_name);
    579   return mrb_iv_get(mrb, self, iv_name);
    580 }
    581 
    582 /* 15.3.1.3.22 */
    583 /*
    584  *  call-seq:
    585  *     obj.instance_variable_set(symbol, obj)    -> obj
    586  *
    587  *  Sets the instance variable names by <i>symbol</i> to
    588  *  <i>object</i>, thereby frustrating the efforts of the class's
    589  *  author to attempt to provide proper encapsulation. The variable
    590  *  did not have to exist prior to this call.
    591  *
    592  *     class Fred
    593  *       def initialize(p1, p2)
    594  *         @a, @b = p1, p2
    595  *       end
    596  *     end
    597  *     fred = Fred.new('cat', 99)
    598  *     fred.instance_variable_set(:@a, 'dog')   #=> "dog"
    599  *     fred.instance_variable_set(:@c, 'cat')   #=> "cat"
    600  *     fred.inspect                             #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">"
    601  */
    602 static mrb_value
    603 mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
    604 {
    605   mrb_sym iv_name;
    606   mrb_value val;
    607 
    608   mrb_get_args(mrb, "no", &iv_name, &val);
    609   mrb_iv_check(mrb, iv_name);
    610   mrb_iv_set(mrb, self, iv_name, val);
    611   return val;
    612508}
    613509
     
    652548KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal)
    653549
    654 static void
    655 method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
    656 {
    657   khint_t i;
    658 
    659   khash_t(mt) *h = klass->mt;
    660   if (!h) return;
    661   for (i=0;i<kh_end(h);i++) {
    662     if (kh_exist(h, i) && kh_value(h, i)) {
    663       kh_put(st, mrb, set, kh_key(h, i));
    664     }
    665   }
    666 }
    667 
    668 mrb_value
    669 mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj)
    670 {
    671   khint_t i;
    672   mrb_value ary;
    673   mrb_bool prepended = FALSE;
    674   struct RClass* oldklass;
    675   khash_t(st)* set = kh_init(st, mrb);
    676 
    677   if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) {
    678     MRB_CLASS_ORIGIN(klass);
    679     prepended = TRUE;
    680   }
    681 
    682   oldklass = 0;
    683   while (klass && (klass != oldklass)) {
    684     method_entry_loop(mrb, klass, set);
    685     if ((klass->tt == MRB_TT_ICLASS && !prepended) ||
    686         (klass->tt == MRB_TT_SCLASS)) {
    687     }
    688     else {
    689       if (!recur) break;
    690     }
    691     oldklass = klass;
    692     klass = klass->super;
    693   }
    694 
    695   ary = mrb_ary_new(mrb);
    696   for (i=0;i<kh_end(set);i++) {
    697     if (kh_exist(set, i)) {
    698       mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
    699     }
    700   }
    701   kh_destroy(st, mrb, set);
    702 
    703   return ary;
    704 }
    705 
    706 static mrb_value
    707 mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
    708 {
    709   khint_t i;
    710   mrb_value ary;
    711   struct RClass* klass;
    712   khash_t(st)* set = kh_init(st, mrb);
    713 
    714   klass = mrb_class(mrb, obj);
    715 
    716   if (klass && (klass->tt == MRB_TT_SCLASS)) {
    717       method_entry_loop(mrb, klass, set);
    718       klass = klass->super;
    719   }
    720   if (recur) {
    721       while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) {
    722         method_entry_loop(mrb, klass, set);
    723         klass = klass->super;
    724       }
    725   }
    726 
    727   ary = mrb_ary_new(mrb);
    728   for (i=0;i<kh_end(set);i++) {
    729     if (kh_exist(set, i)) {
    730       mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
    731     }
    732   }
    733   kh_destroy(st, mrb, set);
    734 
    735   return ary;
    736 }
    737 
    738 static mrb_value
    739 mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag)
    740 {
    741   return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0);
    742 }
    743 /* 15.3.1.3.31 */
    744 /*
    745  *  call-seq:
    746  *     obj.methods    -> array
    747  *
    748  *  Returns a list of the names of methods publicly accessible in
    749  *  <i>obj</i>. This will include all the methods accessible in
    750  *  <i>obj</i>'s ancestors.
    751  *
    752  *     class Klass
    753  *       def kMethod()
    754  *       end
    755  *     end
    756  *     k = Klass.new
    757  *     k.methods[0..9]    #=> [:kMethod, :respond_to?, :nil?, :is_a?,
    758  *                        #    :class, :instance_variable_set,
    759  *                        #    :methods, :extend, :__send__, :instance_eval]
    760  *     k.methods.length   #=> 42
    761  */
    762 static mrb_value
    763 mrb_obj_methods_m(mrb_state *mrb, mrb_value self)
    764 {
    765   mrb_bool recur = TRUE;
    766   mrb_get_args(mrb, "|b", &recur);
    767   return mrb_obj_methods(mrb, recur, self, (mrb_method_flag_t)0); /* everything but private */
    768 }
    769 
    770550/* 15.3.1.3.32 */
    771551/*
     
    780560{
    781561  return mrb_false_value();
    782 }
    783 
    784 /* 15.3.1.3.36 */
    785 /*
    786  *  call-seq:
    787  *     obj.private_methods(all=true)   -> array
    788  *
    789  *  Returns the list of private methods accessible to <i>obj</i>. If
    790  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
    791  *  in the receiver will be listed.
    792  */
    793 static mrb_value
    794 mrb_obj_private_methods(mrb_state *mrb, mrb_value self)
    795 {
    796   mrb_bool recur = TRUE;
    797   mrb_get_args(mrb, "|b", &recur);
    798   return mrb_obj_methods(mrb, recur, self, NOEX_PRIVATE); /* private attribute not define */
    799 }
    800 
    801 /* 15.3.1.3.37 */
    802 /*
    803  *  call-seq:
    804  *     obj.protected_methods(all=true)   -> array
    805  *
    806  *  Returns the list of protected methods accessible to <i>obj</i>. If
    807  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
    808  *  in the receiver will be listed.
    809  */
    810 static mrb_value
    811 mrb_obj_protected_methods(mrb_state *mrb, mrb_value self)
    812 {
    813   mrb_bool recur = TRUE;
    814   mrb_get_args(mrb, "|b", &recur);
    815   return mrb_obj_methods(mrb, recur, self, NOEX_PROTECTED); /* protected attribute not define */
    816 }
    817 
    818 /* 15.3.1.3.38 */
    819 /*
    820  *  call-seq:
    821  *     obj.public_methods(all=true)   -> array
    822  *
    823  *  Returns the list of public methods accessible to <i>obj</i>. If
    824  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
    825  *  in the receiver will be listed.
    826  */
    827 static mrb_value
    828 mrb_obj_public_methods(mrb_state *mrb, mrb_value self)
    829 {
    830   mrb_bool recur = TRUE;
    831   mrb_get_args(mrb, "|b", &recur);
    832   return mrb_obj_methods(mrb, recur, self, NOEX_PUBLIC); /* public attribute not define */
    833562}
    834563
     
    858587{
    859588  mrb_value a[2], exc;
    860   int argc;
     589  mrb_int argc;
    861590
    862591
     
    910639
    911640  mrb_get_args(mrb, "n", &sym);
    912   mrb_iv_check(mrb, sym);
     641  mrb_iv_name_sym_check(mrb, sym);
    913642  val = mrb_iv_remove(mrb, self, sym);
    914643  if (mrb_undef_p(val)) {
    915     mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym));
     644    mrb_name_error(mrb, sym, "instance variable %n not defined", sym);
    916645  }
    917646  return val;
     
    921650mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
    922651{
    923   mrb_sym inspect;
    924   mrb_value repr;
    925 
    926   inspect = mrb_intern_lit(mrb, "inspect");
    927   if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) {
    928     /* method missing in inspect; avoid recursion */
    929     repr = mrb_any_to_s(mrb, self);
    930   }
    931   else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) {
    932     repr = mrb_funcall_argv(mrb, self, inspect, 0, 0);
    933     if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) {
    934       repr = mrb_any_to_s(mrb, self);
    935     }
    936   }
    937   else {
    938     repr = mrb_any_to_s(mrb, self);
    939   }
    940 
    941   mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S",
    942                       mrb_sym2str(mrb, name), repr);
     652  mrb_no_method_error(mrb, name, args, "undefined method '%n'", name);
    943653}
    944654
     
    976686 *     r.mm      #=> 2000
    977687 */
    978 #ifdef MRB_DEFAULT_METHOD_MISSING
    979688static mrb_value
    980689mrb_obj_missing(mrb_state *mrb, mrb_value mod)
     
    984693  mrb_int alen;
    985694
    986   mrb_get_args(mrb, "n*", &name, &a, &alen);
     695  mrb_get_args(mrb, "n*!", &name, &a, &alen);
    987696  mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
    988697  /* not reached */
    989698  return mrb_nil_value();
    990699}
    991 #endif
    992700
    993701static inline mrb_bool
     
    996704  return mrb_respond_to(mrb, obj, id);
    997705}
     706
    998707/* 15.3.1.3.43 */
    999708/*
     
    1015724obj_respond_to(mrb_state *mrb, mrb_value self)
    1016725{
    1017   mrb_value mid;
    1018726  mrb_sym id, rtm_id;
    1019   mrb_bool priv = FALSE, respond_to_p = TRUE;
    1020 
    1021   mrb_get_args(mrb, "o|b", &mid, &priv);
    1022 
    1023   if (mrb_symbol_p(mid)) {
    1024     id = mrb_symbol(mid);
    1025   }
    1026   else {
    1027     mrb_value tmp;
    1028     if (mrb_string_p(mid)) {
    1029       tmp = mrb_check_intern_str(mrb, mid);
    1030     }
    1031     else {
    1032       tmp = mrb_check_string_type(mrb, mid);
    1033       if (mrb_nil_p(tmp)) {
    1034         tmp = mrb_inspect(mrb, mid);
    1035         mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp);
    1036       }
    1037       tmp = mrb_check_intern_str(mrb, tmp);
    1038     }
    1039     if (mrb_nil_p(tmp)) {
    1040       respond_to_p = FALSE;
    1041     }
    1042     else {
    1043       id = mrb_symbol(tmp);
    1044     }
    1045   }
    1046 
    1047   if (respond_to_p) {
    1048     respond_to_p = basic_obj_respond_to(mrb, self, id, !priv);
    1049   }
    1050 
     727  mrb_bool priv = FALSE, respond_to_p;
     728
     729  mrb_get_args(mrb, "n|b", &id, &priv);
     730  respond_to_p = basic_obj_respond_to(mrb, self, id, !priv);
    1051731  if (!respond_to_p) {
    1052732    rtm_id = mrb_intern_lit(mrb, "respond_to_missing?");
    1053733    if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) {
    1054734      mrb_value args[2], v;
    1055       args[0] = mid;
     735      args[0] = mrb_symbol_value(id);
    1056736      args[1] = mrb_bool_value(priv);
    1057737      v = mrb_funcall_argv(mrb, self, rtm_id, 2, args);
     
    1060740  }
    1061741  return mrb_bool_value(respond_to_p);
    1062 }
    1063 
    1064 /* 15.3.1.3.45 */
    1065 /*
    1066  *  call-seq:
    1067  *     obj.singleton_methods(all=true)    -> array
    1068  *
    1069  *  Returns an array of the names of singleton methods for <i>obj</i>.
    1070  *  If the optional <i>all</i> parameter is true, the list will include
    1071  *  methods in modules included in <i>obj</i>.
    1072  *  Only public and protected singleton methods are returned.
    1073  *
    1074  *     module Other
    1075  *       def three() end
    1076  *     end
    1077  *
    1078  *     class Single
    1079  *       def Single.four() end
    1080  *     end
    1081  *
    1082  *     a = Single.new
    1083  *
    1084  *     def a.one()
    1085  *     end
    1086  *
    1087  *     class << a
    1088  *       include Other
    1089  *       def two()
    1090  *       end
    1091  *     end
    1092  *
    1093  *     Single.singleton_methods    #=> [:four]
    1094  *     a.singleton_methods(false)  #=> [:two, :one]
    1095  *     a.singleton_methods         #=> [:two, :one, :three]
    1096  */
    1097 static mrb_value
    1098 mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self)
    1099 {
    1100   mrb_bool recur = TRUE;
    1101   mrb_get_args(mrb, "|b", &recur);
    1102   return mrb_obj_singleton_methods(mrb, recur, self);
    1103 }
    1104 
    1105 static mrb_value
    1106 mod_define_singleton_method(mrb_state *mrb, mrb_value self)
    1107 {
    1108   struct RProc *p;
    1109   mrb_sym mid;
    1110   mrb_value blk = mrb_nil_value();
    1111 
    1112   mrb_get_args(mrb, "n&", &mid, &blk);
    1113   if (mrb_nil_p(blk)) {
    1114     mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    1115   }
    1116   p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
    1117   mrb_proc_copy(p, mrb_proc_ptr(blk));
    1118   p->flags |= MRB_PROC_STRICT;
    1119   mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p);
    1120   return mrb_symbol_value(mid);
    1121742}
    1122743
     
    1138759}
    1139760
    1140 static mrb_value
    1141 mrb_local_variables(mrb_state *mrb, mrb_value self)
    1142 {
    1143   struct RProc *proc;
    1144   mrb_value vars;
    1145   struct mrb_irep *irep;
    1146   size_t i;
    1147 
    1148   proc = mrb->c->ci[-1].proc;
    1149 
    1150   if (MRB_PROC_CFUNC_P(proc)) {
    1151     return mrb_ary_new(mrb);
    1152   }
    1153 
    1154   irep = proc->body.irep;
    1155   if (!irep->lv) {
    1156     return mrb_ary_new(mrb);
    1157   }
    1158   vars = mrb_hash_new(mrb);
    1159   for (i = 0; i + 1 < irep->nlocals; ++i) {
    1160     if (irep->lv[i].name) {
    1161       mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
    1162     }
    1163   }
    1164   if (proc->env) {
    1165     struct REnv *e = proc->env;
    1166 
    1167     while (e) {
    1168       if (MRB_ENV_STACK_SHARED_P(e) &&
    1169           !MRB_PROC_CFUNC_P(e->cxt.c->cibase[e->cioff].proc)) {
    1170         irep = e->cxt.c->cibase[e->cioff].proc->body.irep;
    1171         if (irep->lv) {
    1172           for (i = 0; i + 1 < irep->nlocals; ++i) {
    1173             if (irep->lv[i].name) {
    1174               mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
    1175             }
    1176           }
    1177         }
    1178       }
    1179       e = (struct REnv*)e->c;
    1180     }
    1181   }
    1182 
    1183   return mrb_hash_keys(mrb, vars);
    1184 }
    1185 
    1186761mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value);
     762
    1187763void
    1188764mrb_init_kernel(mrb_state *mrb)
     
    1192768  mrb->kernel_module = krn = mrb_define_module(mrb, "Kernel");                                                    /* 15.3.1 */
    1193769  mrb_define_class_method(mrb, krn, "block_given?",         mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.2.2  */
    1194   mrb_define_class_method(mrb, krn, "global_variables",     mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.2.4  */
    1195770  mrb_define_class_method(mrb, krn, "iterator?",            mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.2.5  */
    1196   mrb_define_class_method(mrb, krn, "local_variables",      mrb_local_variables,             MRB_ARGS_NONE());    /* 15.3.1.2.7  */
    1197771;     /* 15.3.1.2.11 */
    1198772  mrb_define_class_method(mrb, krn, "raise",                mrb_f_raise,                     MRB_ARGS_OPT(2));    /* 15.3.1.2.12 */
    1199773
    1200   mrb_define_method(mrb, krn, "singleton_class",            mrb_singleton_class,             MRB_ARGS_NONE());
    1201774
    1202775  mrb_define_method(mrb, krn, "===",                        mrb_equal_m,                     MRB_ARGS_REQ(1));    /* 15.3.1.3.2  */
     
    1206779  mrb_define_method(mrb, krn, "dup",                        mrb_obj_dup,                     MRB_ARGS_NONE());    /* 15.3.1.3.9  */
    1207780  mrb_define_method(mrb, krn, "eql?",                       mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.10 */
    1208   mrb_define_method(mrb, krn, "equal?",                     mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.11 */
    1209781  mrb_define_method(mrb, krn, "extend",                     mrb_obj_extend_m,                MRB_ARGS_ANY());     /* 15.3.1.3.13 */
    1210782  mrb_define_method(mrb, krn, "freeze",                     mrb_obj_freeze,                  MRB_ARGS_NONE());
    1211783  mrb_define_method(mrb, krn, "frozen?",                    mrb_obj_frozen,                  MRB_ARGS_NONE());
    1212   mrb_define_method(mrb, krn, "global_variables",           mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.3.14 */
    1213784  mrb_define_method(mrb, krn, "hash",                       mrb_obj_hash,                    MRB_ARGS_NONE());    /* 15.3.1.3.15 */
    1214785  mrb_define_method(mrb, krn, "initialize_copy",            mrb_obj_init_copy,               MRB_ARGS_REQ(1));    /* 15.3.1.3.16 */
    1215786  mrb_define_method(mrb, krn, "inspect",                    mrb_obj_inspect,                 MRB_ARGS_NONE());    /* 15.3.1.3.17 */
    1216787  mrb_define_method(mrb, krn, "instance_of?",               obj_is_instance_of,              MRB_ARGS_REQ(1));    /* 15.3.1.3.19 */
    1217   mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined,            MRB_ARGS_REQ(1));    /* 15.3.1.3.20 */
    1218   mrb_define_method(mrb, krn, "instance_variable_get",      mrb_obj_ivar_get,                MRB_ARGS_REQ(1));    /* 15.3.1.3.21 */
    1219   mrb_define_method(mrb, krn, "instance_variable_set",      mrb_obj_ivar_set,                MRB_ARGS_REQ(2));    /* 15.3.1.3.22 */
    1220   mrb_define_method(mrb, krn, "instance_variables",         mrb_obj_instance_variables,      MRB_ARGS_NONE());    /* 15.3.1.3.23 */
     788
    1221789  mrb_define_method(mrb, krn, "is_a?",                      mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.24 */
    1222790  mrb_define_method(mrb, krn, "iterator?",                  mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.3.25 */
    1223791  mrb_define_method(mrb, krn, "kind_of?",                   mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.26 */
    1224   mrb_define_method(mrb, krn, "local_variables",            mrb_local_variables,             MRB_ARGS_NONE());    /* 15.3.1.3.28 */
    1225 #ifdef MRB_DEFAULT_METHOD_MISSING
    1226792  mrb_define_method(mrb, krn, "method_missing",             mrb_obj_missing,                 MRB_ARGS_ANY());     /* 15.3.1.3.30 */
    1227 #endif
    1228   mrb_define_method(mrb, krn, "methods",                    mrb_obj_methods_m,               MRB_ARGS_OPT(1));    /* 15.3.1.3.31 */
    1229793  mrb_define_method(mrb, krn, "nil?",                       mrb_false,                       MRB_ARGS_NONE());    /* 15.3.1.3.32 */
    1230794  mrb_define_method(mrb, krn, "object_id",                  mrb_obj_id_m,                    MRB_ARGS_NONE());    /* 15.3.1.3.33 */
    1231   mrb_define_method(mrb, krn, "private_methods",            mrb_obj_private_methods,         MRB_ARGS_OPT(1));    /* 15.3.1.3.36 */
    1232   mrb_define_method(mrb, krn, "protected_methods",          mrb_obj_protected_methods,       MRB_ARGS_OPT(1));    /* 15.3.1.3.37 */
    1233   mrb_define_method(mrb, krn, "public_methods",             mrb_obj_public_methods,          MRB_ARGS_OPT(1));    /* 15.3.1.3.38 */
    1234795  mrb_define_method(mrb, krn, "raise",                      mrb_f_raise,                     MRB_ARGS_ANY());     /* 15.3.1.3.40 */
    1235796  mrb_define_method(mrb, krn, "remove_instance_variable",   mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1));    /* 15.3.1.3.41 */
    1236   mrb_define_method(mrb, krn, "respond_to?",                obj_respond_to,                  MRB_ARGS_ANY());     /* 15.3.1.3.43 */
    1237   mrb_define_method(mrb, krn, "send",                       mrb_f_send,                      MRB_ARGS_ANY());     /* 15.3.1.3.44 */
    1238   mrb_define_method(mrb, krn, "singleton_methods",          mrb_obj_singleton_methods_m,     MRB_ARGS_OPT(1));    /* 15.3.1.3.45 */
    1239   mrb_define_method(mrb, krn, "define_singleton_method",    mod_define_singleton_method,     MRB_ARGS_ANY());
     797  mrb_define_method(mrb, krn, "respond_to?",                obj_respond_to,                  MRB_ARGS_ARG(1,1));     /* 15.3.1.3.43 */
    1240798  mrb_define_method(mrb, krn, "to_s",                       mrb_any_to_s,                    MRB_ARGS_NONE());    /* 15.3.1.3.46 */
    1241799  mrb_define_method(mrb, krn, "__case_eqq",                 mrb_obj_ceqq,                    MRB_ARGS_REQ(1));    /* internal */
     800  mrb_define_method(mrb, krn, "__to_int",                   mrb_to_int,                      MRB_ARGS_NONE()); /* internal */
     801  mrb_define_method(mrb, krn, "__to_str",                   mrb_to_str,                      MRB_ARGS_NONE()); /* internal */
    1242802
    1243803  mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
    1244   mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone"));
    1245 }
     804}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/load.c

    r331 r439  
    88#include <stdlib.h>
    99#include <string.h>
     10#include <math.h>
    1011#include <mruby/dump.h>
    1112#include <mruby/irep.h>
     
    2526#define FLAG_SRC_STATIC 0
    2627
    27 #define SIZE_ERROR_MUL(nmemb, size) ((nmemb) > SIZE_MAX / (size))
     28#define SIZE_ERROR_MUL(nmemb, size) ((size_t)(nmemb) > SIZE_MAX / (size))
    2829
    2930static size_t
     
    4142}
    4243
     44#ifndef MRB_WITHOUT_FLOAT
     45double mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck);
     46
     47static double
     48str_to_double(mrb_state *mrb, const char *p, size_t len)
     49{
     50  /* `i`, `inf`, `infinity` */
     51  if (len > 0 && p[0] == 'i') return INFINITY;
     52
     53  /* `I`, `-inf`, `-infinity` */
     54  if (p[0] == 'I' || (len > 1 && p[0] == '-' && p[1] == 'i')) return -INFINITY;
     55  return mrb_str_len_to_dbl(mrb, p, len, TRUE);
     56}
     57#endif
     58
     59mrb_value mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, int badcheck);
     60
    4361static mrb_irep*
    4462read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
    4563{
    46   size_t i;
     64  int i;
    4765  const uint8_t *src = bin;
    4866  ptrdiff_t diff;
    4967  uint16_t tt, pool_data_len, snl;
    50   size_t plen;
     68  int plen;
    5169  int ai = mrb_gc_arena_save(mrb);
    5270  mrb_irep *irep = mrb_add_irep(mrb);
     
    6987  /* Binary Data Section */
    7088  /* ISEQ BLOCK */
    71   irep->ilen = (size_t)bin_to_uint32(src);
     89  irep->ilen = (uint16_t)bin_to_uint32(src);
    7290  src += sizeof(uint32_t);
    7391  src += skip_padding(src);
     
    8098        (flags & FLAG_BYTEORDER_NATIVE)) {
    8199      irep->iseq = (mrb_code*)src;
    82       src += sizeof(uint32_t) * irep->ilen;
     100      src += sizeof(mrb_code) * irep->ilen;
    83101      irep->flags |= MRB_ISEQ_NO_FREE;
    84102    }
    85103    else {
    86       irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
    87       if (flags & FLAG_BYTEORDER_NATIVE) {
    88         memcpy(irep->iseq, src, sizeof(uint32_t) * irep->ilen);
    89         src += sizeof(uint32_t) * irep->ilen;
    90       }
    91       else if (flags & FLAG_BYTEORDER_BIG) {
    92         for (i = 0; i < irep->ilen; i++) {
    93           irep->iseq[i] = (mrb_code)bin_to_uint32(src);     /* iseq */
    94           src += sizeof(uint32_t);
    95         }
    96       }
    97       else {
    98         for (i = 0; i < irep->ilen; i++) {
    99           irep->iseq[i] = (mrb_code)bin_to_uint32l(src);     /* iseq */
    100           src += sizeof(uint32_t);
    101         }
    102       }
     104      size_t data_len = sizeof(mrb_code) * irep->ilen;
     105      void *buf = mrb_malloc(mrb, data_len);
     106      irep->iseq = (mrb_code *)buf;
     107      memcpy(buf, src, data_len);
     108      src += data_len;
    103109    }
    104110  }
    105111
    106112  /* POOL BLOCK */
    107   plen = (size_t)bin_to_uint32(src); /* number of pool */
     113  plen = bin_to_uint32(src); /* number of pool */
    108114  src += sizeof(uint32_t);
    109115  if (plen > 0) {
     
    114120
    115121    for (i = 0; i < plen; i++) {
    116       mrb_value s;
     122      const char *s;
     123      mrb_bool st = (flags & FLAG_SRC_MALLOC)==0;
    117124
    118125      tt = *src++; /* pool TT */
    119126      pool_data_len = bin_to_uint16(src); /* pool data length */
    120127      src += sizeof(uint16_t);
    121       if (flags & FLAG_SRC_MALLOC) {
    122         s = mrb_str_new(mrb, (char *)src, pool_data_len);
    123       }
    124       else {
    125         s = mrb_str_new_static(mrb, (char *)src, pool_data_len);
    126       }
     128      s = (const char*)src;
    127129      src += pool_data_len;
    128130      switch (tt) { /* pool data */
    129       case IREP_TT_FIXNUM:
    130         irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE);
     131      case IREP_TT_FIXNUM: {
     132        mrb_value num = mrb_str_len_to_inum(mrb, s, pool_data_len, 10, FALSE);
     133#ifdef MRB_WITHOUT_FLOAT
     134        irep->pool[i] = num;
     135#else
     136        irep->pool[i] = mrb_float_p(num)? mrb_float_pool(mrb, mrb_float(num)) : num;
     137#endif
     138        }
    131139        break;
    132140
     141#ifndef MRB_WITHOUT_FLOAT
    133142      case IREP_TT_FLOAT:
    134         irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE));
     143        irep->pool[i] = mrb_float_pool(mrb, str_to_double(mrb, s, pool_data_len));
    135144        break;
     145#endif
    136146
    137147      case IREP_TT_STRING:
    138         irep->pool[i] = mrb_str_pool(mrb, s);
     148        irep->pool[i] = mrb_str_pool(mrb, s, pool_data_len, st);
    139149        break;
    140150
     
    150160
    151161  /* SYMS BLOCK */
    152   irep->slen = (size_t)bin_to_uint32(src);  /* syms length */
     162  irep->slen = (uint16_t)bin_to_uint32(src);  /* syms length */
    153163  src += sizeof(uint32_t);
    154164  if (irep->slen > 0) {
     
    192202{
    193203  mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags);
    194   size_t i;
     204  int i;
    195205
    196206  if (irep == NULL) {
     
    222232
    223233static int
    224 read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len)
    225 {
    226   size_t i, fname_len, niseq;
    227   char *fname;
    228   uint16_t *lines;
    229 
    230   *len = 0;
    231   bin += sizeof(uint32_t); /* record size */
    232   *len += sizeof(uint32_t);
    233   fname_len = bin_to_uint16(bin);
    234   bin += sizeof(uint16_t);
    235   *len += sizeof(uint16_t);
    236   fname = (char *)mrb_malloc(mrb, fname_len + 1);
    237   memcpy(fname, bin, fname_len);
    238   fname[fname_len] = '\0';
    239   bin += fname_len;
    240   *len += fname_len;
    241 
    242   niseq = (size_t)bin_to_uint32(bin);
    243   bin += sizeof(uint32_t); /* niseq */
    244   *len += sizeof(uint32_t);
    245 
    246   if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) {
    247     return MRB_DUMP_GENERAL_FAILURE;
    248   }
    249   lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t));
    250   for (i = 0; i < niseq; i++) {
    251     lines[i] = bin_to_uint16(bin);
    252     bin += sizeof(uint16_t); /* niseq */
    253     *len += sizeof(uint16_t);
    254   }
    255 
    256   irep->filename = fname;
    257   irep->lines = lines;
    258   return MRB_DUMP_OK;
    259 }
    260 
    261 static int
    262 read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp)
    263 {
    264   int result = read_lineno_record_1(mrb, bin, irep, lenp);
    265   size_t i;
    266 
    267   if (result != MRB_DUMP_OK) return result;
    268   for (i = 0; i < irep->rlen; i++) {
    269     size_t len;
    270 
    271     result = read_lineno_record(mrb, bin, irep->reps[i], &len);
    272     if (result != MRB_DUMP_OK) break;
    273     bin += len;
    274     *lenp += len;
    275   }
    276   return result;
    277 }
    278 
    279 static int
    280 read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep)
    281 {
    282   size_t len;
    283 
    284   len = 0;
    285   bin += sizeof(struct rite_section_lineno_header);
    286 
    287   /* Read Binary Data Section */
    288   return read_lineno_record(mrb, bin, irep, &len);
    289 }
    290 
    291 static int
    292234read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len)
    293235{
    294236  const uint8_t *bin = start;
    295237  ptrdiff_t diff;
    296   size_t record_size, i;
     238  size_t record_size;
    297239  uint16_t f_idx;
     240  int i;
    298241
    299242  if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; }
    300243
    301244  irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info));
    302   irep->debug_info->pc_count = irep->ilen;
     245  irep->debug_info->pc_count = (uint32_t)irep->ilen;
    303246
    304247  record_size = (size_t)bin_to_uint32(bin);
     
    312255    mrb_irep_debug_info_file *file;
    313256    uint16_t filename_idx;
    314     mrb_int len;
    315257
    316258    file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file));
     
    325267    mrb_assert(filename_idx < filenames_len);
    326268    file->filename_sym = filenames[filename_idx];
    327     len = 0;
    328     file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len);
    329269
    330270    file->line_entry_count = bin_to_uint32(bin);
     
    433373{
    434374  const uint8_t *bin = start;
    435   size_t i;
    436375  ptrdiff_t diff;
     376  int i;
    437377
    438378  irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (irep->nlocals - 1));
     
    517457
    518458static int
    519 read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags)
     459read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint16_t *crc, uint8_t *flags)
    520460{
    521461  const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
     462
     463  if (bufsize < sizeof(struct rite_binary_header)) {
     464    return MRB_DUMP_READ_FAULT;
     465  }
    522466
    523467  if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) {
     
    537481  }
    538482
     483  if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) {
     484    return MRB_DUMP_INVALID_FILE_HEADER;
     485  }
     486
    539487  if (crc) {
    540488    *crc = bin_to_uint16(header->binary_crc);
     
    542490  *bin_size = (size_t)bin_to_uint32(header->binary_size);
    543491
     492  if (bufsize < *bin_size) {
     493    return MRB_DUMP_READ_FAULT;
     494  }
     495
    544496  return MRB_DUMP_OK;
    545497}
    546498
    547499static mrb_irep*
    548 read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
     500read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags)
    549501{
    550502  int result;
     
    559511  }
    560512
    561   result = read_binary_header(bin, &bin_size, &crc, &flags);
     513  result = read_binary_header(bin, bufsize, &bin_size, &crc, &flags);
    562514  if (result != MRB_DUMP_OK) {
    563515    return NULL;
     
    576528      if (!irep) return NULL;
    577529    }
    578     else if (memcmp(section_header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(section_header->section_ident)) == 0) {
    579       if (!irep) return NULL;   /* corrupted data */
    580       result = read_section_lineno(mrb, bin, irep);
    581       if (result < MRB_DUMP_OK) {
    582         return NULL;
    583       }
    584     }
    585530    else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) {
    586531      if (!irep) return NULL;   /* corrupted data */
     
    606551mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
    607552{
    608 #ifdef MRB_USE_ETEXT_EDATA
     553#if defined(MRB_USE_LINK_TIME_RO_DATA_P) || defined(MRB_USE_CUSTOM_RO_DATA_P)
    609554  uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC;
    610555#else
     
    612557#endif
    613558
    614   return read_irep(mrb, bin, flags);
     559  return read_irep(mrb, bin, (size_t)-1, flags);
     560}
     561
     562MRB_API mrb_irep*
     563mrb_read_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize)
     564{
     565  return read_irep(mrb, (const uint8_t *)buf, bufsize, FLAG_SRC_MALLOC);
    615566}
    616567
     
    623574}
    624575
    625 MRB_API mrb_value
    626 mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c)
    627 {
    628   mrb_irep *irep = mrb_read_irep(mrb, bin);
     576void mrb_codedump_all(mrb_state*, struct RProc*);
     577
     578static mrb_value
     579load_irep(mrb_state *mrb, mrb_irep *irep, mrbc_context *c)
     580{
    629581  struct RProc *proc;
    630582
     
    634586  }
    635587  proc = mrb_proc_new(mrb, irep);
     588  proc->c = NULL;
    636589  mrb_irep_decref(mrb, irep);
     590  if (c && c->dump_result) mrb_codedump_all(mrb, proc);
    637591  if (c && c->no_exec) return mrb_obj_value(proc);
    638592  return mrb_top_run(mrb, proc, mrb_top_self(mrb), 0);
     
    640594
    641595MRB_API mrb_value
     596mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c)
     597{
     598  return load_irep(mrb, mrb_read_irep(mrb, bin), c);
     599}
     600
     601MRB_API mrb_value
     602mrb_load_irep_buf_cxt(mrb_state *mrb, const void *buf, size_t bufsize, mrbc_context *c)
     603{
     604  return load_irep(mrb, mrb_read_irep_buf(mrb, buf, bufsize), c);
     605}
     606
     607MRB_API mrb_value
    642608mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
    643609{
    644610  return mrb_load_irep_cxt(mrb, bin, NULL);
     611}
     612
     613MRB_API mrb_value
     614mrb_load_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize)
     615{
     616  return mrb_load_irep_buf_cxt(mrb, buf, bufsize, NULL);
    645617}
    646618
     
    665637    goto irep_exit;
    666638  }
    667   result = read_binary_header(buf, &buf_size, NULL, &flags);
     639  result = read_binary_header(buf, (size_t)-1, &buf_size, NULL, &flags);
    668640  if (result != MRB_DUMP_OK || buf_size <= header_size) {
    669641    goto irep_exit;
     
    674646    goto irep_exit;
    675647  }
    676   irep = read_irep(mrb, buf, FLAG_SRC_MALLOC);
     648  irep = read_irep(mrb, buf, (size_t)-1, FLAG_SRC_MALLOC);
    677649
    678650irep_exit:
     
    681653}
    682654
    683 void mrb_codedump_all(mrb_state*, struct RProc*);
    684 
    685655MRB_API mrb_value
    686656mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c)
    687657{
    688   mrb_irep *irep = mrb_read_irep_file(mrb, fp);
    689   mrb_value val;
    690   struct RProc *proc;
    691 
    692   if (!irep) {
    693     irep_error(mrb);
    694     return mrb_nil_value();
    695   }
    696   proc = mrb_proc_new(mrb, irep);
    697   mrb_irep_decref(mrb, irep);
    698   if (c && c->dump_result) mrb_codedump_all(mrb, proc);
    699   if (c && c->no_exec) return mrb_obj_value(proc);
    700   val = mrb_top_run(mrb, proc, mrb_top_self(mrb), 0);
    701   return val;
     658  return load_irep(mrb, mrb_read_irep_file(mrb, fp), c);
    702659}
    703660
  • EcnlProtoTool/trunk/mruby-2.1.1/src/mruby_core.rake

    r331 r439  
    1212    objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" }
    1313  end
    14   self.libmruby << objs
     14  self.libmruby_objs << objs
    1515
    16   file libfile("#{build_dir}/lib/libmruby_core") => objs do |t|
     16  file libmruby_core_static => objs do |t|
    1717    archiver.run t.name, t.prerequisites
    1818  end
  • EcnlProtoTool/trunk/mruby-2.1.1/src/numeric.c

    r331 r439  
    55*/
    66
     7#ifndef MRB_WITHOUT_FLOAT
    78#include <float.h>
     9#include <math.h>
     10#endif
    811#include <limits.h>
    9 #include <math.h>
    1012#include <stdlib.h>
     13#include <string.h>
    1114
    1215#include <mruby.h>
     
    1619#include <mruby/class.h>
    1720
     21#ifndef MRB_WITHOUT_FLOAT
    1822#ifdef MRB_USE_FLOAT
    1923#define trunc(f) truncf(f)
     
    2125#define ceil(f) ceilf(f)
    2226#define fmod(x,y) fmodf(x,y)
    23 #define MRB_FLO_TO_STR_FMT "%.7g"
    24 #else
    25 #define MRB_FLO_TO_STR_FMT "%.14g"
    26 #endif
    27 
     27#define FLO_TO_STR_PREC 8
     28#else
     29#define FLO_TO_STR_PREC 16
     30#endif
     31#endif
     32
     33#ifndef MRB_WITHOUT_FLOAT
    2834MRB_API mrb_float
    2935mrb_to_flo(mrb_state *mrb, mrb_value val)
     
    4046}
    4147
     48MRB_API mrb_value
     49mrb_int_value(mrb_state *mrb, mrb_float f)
     50{
     51  if (FIXABLE_FLOAT(f)) {
     52    return mrb_fixnum_value((mrb_int)f);
     53  }
     54  return mrb_float_value(mrb, f);
     55}
     56#endif
     57
    4258/*
    4359 * call-seq:
     
    5066 */
    5167static mrb_value
    52 num_pow(mrb_state *mrb, mrb_value x)
    53 {
    54   mrb_value y;
     68integral_pow(mrb_state *mrb, mrb_value x)
     69{
     70  mrb_value y;
     71#ifndef MRB_WITHOUT_FLOAT
    5572  mrb_float d;
     73#endif
    5674
    5775  mrb_get_args(mrb, "o", &y);
     
    6280    mrb_int result = 1;
    6381
    64     if (exp < 0) goto float_pow;
     82    if (exp < 0)
     83#ifdef MRB_WITHOUT_FLOAT
     84      return mrb_fixnum_value(0);
     85#else
     86      goto float_pow;
     87#endif
    6588    for (;;) {
    6689      if (exp & 1) {
    6790        if (mrb_int_mul_overflow(result, base, &result)) {
     91#ifndef MRB_WITHOUT_FLOAT
    6892          goto float_pow;
     93#endif
    6994        }
    7095      }
     
    7297      if (exp == 0) break;
    7398      if (mrb_int_mul_overflow(base, base, &base)) {
     99#ifndef MRB_WITHOUT_FLOAT
    74100        goto float_pow;
     101#endif
    75102      }
    76103    }
    77104    return mrb_fixnum_value(result);
    78105  }
     106#ifdef MRB_WITHOUT_FLOAT
     107  mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     108#else
    79109 float_pow:
    80110  d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y));
    81111  return mrb_float_value(mrb, d);
     112#endif
     113}
     114
     115static mrb_value
     116integral_idiv(mrb_state *mrb, mrb_value x)
     117{
     118#ifdef MRB_WITHOUT_FLOAT
     119  mrb_value y;
     120
     121  mrb_get_args(mrb, "o", &y);
     122  if (!mrb_fixnum_p(y)) {
     123    mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     124  }
     125  return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
     126#else
     127  mrb_float y;
     128
     129  mrb_get_args(mrb, "f", &y);
     130  return mrb_int_value(mrb, mrb_to_flo(mrb, x) / y);
     131#endif
    82132}
    83133
     
    93143 */
    94144
    95 mrb_value
    96 mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
    97 {
    98   return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
    99 }
    100 
    101145/* 15.2.9.3.19(x) */
    102146/*
     
    108152
    109153static mrb_value
    110 num_div(mrb_state *mrb, mrb_value x)
    111 {
     154integral_div(mrb_state *mrb, mrb_value x)
     155{
     156#ifdef MRB_WITHOUT_FLOAT
     157  mrb_value y;
     158
     159  mrb_get_args(mrb, "o", &y);
     160  if (!mrb_fixnum_p(y)) {
     161    mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     162  }
     163  return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
     164#else
    112165  mrb_float y;
    113166
    114167  mrb_get_args(mrb, "f", &y);
    115168  return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y);
    116 }
    117 
     169#endif
     170}
     171
     172static mrb_value
     173integral_coerce_step_counter(mrb_state *mrb, mrb_value self)
     174{
     175  mrb_value num, step;
     176
     177  mrb_get_args(mrb, "oo", &num, &step);
     178
     179#ifndef MRB_WITHOUT_FLOAT
     180  if (mrb_float_p(self) || mrb_float_p(num) || mrb_float_p(step)) {
     181    return mrb_Float(mrb, self);
     182  }
     183#endif
     184
     185  return self;
     186}
     187
     188#ifndef MRB_WITHOUT_FLOAT
    118189/********************************************************************
    119190 *
     
    139210flo_to_s(mrb_state *mrb, mrb_value flt)
    140211{
    141   if (isnan(mrb_float(flt))) {
     212  mrb_float f = mrb_float(flt);
     213
     214  if (isinf(f)) {
     215    return f < 0 ? mrb_str_new_lit(mrb, "-Infinity")
     216                 : mrb_str_new_lit(mrb, "Infinity");
     217  }
     218  else if (isnan(f)) {
    142219    return mrb_str_new_lit(mrb, "NaN");
    143220  }
    144   return mrb_float_to_str(mrb, flt, MRB_FLO_TO_STR_FMT);
     221  else {
     222    char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g";
     223    mrb_value str = mrb_float_to_str(mrb, flt, fmt);
     224    mrb_int len;
     225    char *begp, *p, *endp;
     226
     227    insert_dot_zero:
     228    begp = RSTRING_PTR(str);
     229    len = RSTRING_LEN(str);
     230    for (p = begp, endp = p + len; p < endp; ++p) {
     231      if (*p == '.') {
     232        return str;
     233      }
     234      else if (*p == 'e') {
     235        ptrdiff_t e_pos = p - begp;
     236        mrb_str_cat(mrb, str, ".0", 2);
     237        p = RSTRING_PTR(str) + e_pos;
     238        memmove(p + 2, p, len - e_pos);
     239        memcpy(p, ".0", 2);
     240        return str;
     241      }
     242    }
     243
     244    if (FLO_TO_STR_PREC + (begp[0] == '-') <= len) {
     245      --fmt[sizeof(fmt) - 3];  /* %.16g(%.8g) -> %.15g(%.7g) */
     246      str = mrb_float_to_str(mrb, flt, fmt);
     247      goto insert_dot_zero;
     248    }
     249
     250    return str;
     251  }
    145252}
    146253
     
    182289
    183290static void
    184 flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp)
    185 {
    186   mrb_float div;
    187   mrb_float mod;
    188 
     291flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp)
     292{
     293  double div, mod;
     294
     295  if (isnan(y)) {
     296    /* y is NaN so all results are NaN */
     297    div = mod = y;
     298    goto exit;
     299  }
    189300  if (y == 0.0) {
    190     div = INFINITY;
     301    if (x == 0) div = NAN;
     302    else if (x > 0.0) div = INFINITY;
     303    else div = -INFINITY;       /* x < 0.0 */
    191304    mod = NAN;
     305    goto exit;
     306  }
     307  if ((x == 0.0) || (isinf(y) && !isinf(x))) {
     308    mod = x;
    192309  }
    193310  else {
    194311    mod = fmod(x, y);
    195     if (isinf(x) && isfinite(y))
    196       div = x;
    197     else
    198       div = (x - mod) / y;
    199     if (y*mod < 0) {
    200       mod += y;
    201       div -= 1.0;
    202     }
    203   }
    204 
     312  }
     313  if (isinf(x) && !isinf(y)) {
     314    div = x;
     315  }
     316  else {
     317    div = (x - mod) / y;
     318    if (modp && divp) div = round(div);
     319  }
     320  if (div == 0) div = 0.0;
     321  if (mod == 0) mod = 0.0;
     322  if (y*mod < 0) {
     323    mod += y;
     324    div -= 1.0;
     325  }
     326 exit:
    205327  if (modp) *modp = mod;
    206328  if (divp) *divp = div;
     
    230352  return mrb_float_value(mrb, mod);
    231353}
     354#endif
    232355
    233356/* 15.2.8.3.16 */
     
    253376}
    254377
     378#ifndef MRB_WITHOUT_FLOAT
    255379static mrb_value
    256380flo_eql(mrb_state *mrb, mrb_value x)
     
    260384  mrb_get_args(mrb, "o", &y);
    261385  if (!mrb_float_p(y)) return mrb_false_value();
    262   return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y));
     386  return mrb_bool_value(mrb_float(x) == mrb_float(y));
    263387}
    264388
     
    312436int64_value(mrb_state *mrb, int64_t v)
    313437{
    314   if (FIXABLE(v)) {
     438  if (TYPED_FIXABLE(v,int64_t)) {
    315439    return mrb_fixnum_value((mrb_int)v);
    316440  }
     
    322446{
    323447  int64_t v1;
    324   mrb_get_args(mrb, "");
    325448  v1 = (int64_t)mrb_float(x);
    326449  return int64_value(mrb, ~v1);
     
    375498    while (width++) {
    376499      val /= 2;
     500      if (val < 1.0) {
     501        val = 0;
     502        break;
     503      }
    377504    }
    378505#if defined(_ISOC99_SOURCE)
    379506    val = trunc(val);
    380507#else
    381     val = val > 0 ? floor(val) : ceil(val);
     508    if (val > 0){
     509        val = floor(val);
     510    } else {
     511        val = ceil(val);
     512    }
    382513#endif
    383514    if (val == 0 && mrb_float(x) < 0) {
     
    390521    }
    391522  }
    392   if (FIXABLE_FLOAT(val)) {
    393     return mrb_fixnum_value((mrb_int)val);
    394   }
    395   return mrb_float_value(mrb, val);
    396 }
    397 
    398 static mrb_value
    399 flo_lshift(mrb_state *mrb, mrb_value x)
     523  return mrb_int_value(mrb, val);
     524}
     525
     526static mrb_value
     527flo_rshift(mrb_state *mrb, mrb_value x)
    400528{
    401529  mrb_int width;
     
    406534
    407535static mrb_value
    408 flo_rshift(mrb_state *mrb, mrb_value x)
     536flo_lshift(mrb_state *mrb, mrb_value x)
    409537{
    410538  mrb_int width;
     
    412540  mrb_get_args(mrb, "i", &width);
    413541  return flo_shift(mrb, x, width);
    414 }
    415 
    416 /* 15.2.8.3.18 */
    417 /*
    418  * call-seq:
    419  *   flt.hash  ->  integer
    420  *
    421  * Returns a hash code for this float.
    422  */
    423 static mrb_value
    424 flo_hash(mrb_state *mrb, mrb_value num)
    425 {
    426   mrb_float d;
    427   char *c;
    428   size_t i;
    429   mrb_int hash;
    430 
    431   d = (mrb_float)mrb_fixnum(num);
    432   /* normalize -0.0 to 0.0 */
    433   if (d == 0) d = 0.0;
    434   c = (char*)&d;
    435   for (hash=0,i=0; i<sizeof(mrb_float); i++) {
    436     hash = (hash * 971) ^ (unsigned char)c[i];
    437   }
    438   if (hash < 0) hash = -hash;
    439   return mrb_fixnum_value(hash);
    440542}
    441543
     
    525627
    526628  mrb_check_num_exact(mrb, f);
    527   if (!FIXABLE_FLOAT(f)) {
    528     return mrb_float_value(mrb, f);
    529   }
    530   return mrb_fixnum_value((mrb_int)f);
     629  return mrb_int_value(mrb, f);
    531630}
    532631
     
    551650
    552651  mrb_check_num_exact(mrb, f);
    553   if (!FIXABLE_FLOAT(f)) {
    554     return mrb_float_value(mrb, f);
    555   }
    556   return mrb_fixnum_value((mrb_int)f);
     652  return mrb_int_value(mrb, f);
    557653}
    558654
     
    605701  f = 1.0;
    606702  i = ndigits >= 0 ? ndigits : -ndigits;
     703  if (ndigits > DBL_DIG+2) return num;
    607704  while  (--i >= 0)
    608705    f = f*10.0;
     
    635732    return mrb_float_value(mrb, number);
    636733  }
    637   return mrb_fixnum_value((mrb_int)number);
     734  return mrb_int_value(mrb, number);
    638735}
    639736
     
    643740 *  call-seq:
    644741 *     flt.to_i      ->  integer
    645  *     flt.to_int    ->  integer
    646742 *     flt.truncate  ->  integer
    647743 *
     
    658754
    659755  mrb_check_num_exact(mrb, f);
    660   if (!FIXABLE_FLOAT(f)) {
    661     return mrb_float_value(mrb, f);
    662   }
    663   return mrb_fixnum_value((mrb_int)f);
     756  return mrb_int_value(mrb, f);
    664757}
    665758
     
    669762  return mrb_bool_value(isnan(mrb_float(num)));
    670763}
     764#endif
    671765
    672766/*
     
    682776 *  call-seq:
    683777 *     int.to_i      ->  integer
    684  *     int.to_int    ->  integer
    685778 *
    686779 *  As <i>int</i> is already an <code>Integer</code>, all these
     
    694787}
    695788
    696 mrb_value
    697 mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
     789static mrb_value
     790fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
    698791{
    699792  mrb_int a;
     
    706799    b = mrb_fixnum(y);
    707800    if (mrb_int_mul_overflow(a, b, &c)) {
     801#ifndef MRB_WITHOUT_FLOAT
    708802      return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b);
     803#endif
    709804    }
    710805    return mrb_fixnum_value(c);
    711806  }
     807#ifdef MRB_WITHOUT_FLOAT
     808  mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     809#else
    712810  return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y));
     811#endif
     812}
     813
     814MRB_API mrb_value
     815mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y)
     816{
     817  if (mrb_fixnum_p(x)) {
     818    return fixnum_mul(mrb, x, y);
     819  }
     820#ifndef MRB_WITHOUT_FLOAT
     821  if (mrb_float_p(x)) {
     822    return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y));
     823  }
     824#endif
     825  mrb_raise(mrb, E_TYPE_ERROR, "no number multiply");
     826  return mrb_nil_value();       /* not reached */
    713827}
    714828
     
    729843
    730844  mrb_get_args(mrb, "o", &y);
    731   return mrb_fixnum_mul(mrb, x, y);
     845  return fixnum_mul(mrb, x, y);
    732846}
    733847
     
    774888{
    775889  mrb_value y;
    776   mrb_int a;
     890  mrb_int a, b;
    777891
    778892  mrb_get_args(mrb, "o", &y);
    779893  a = mrb_fixnum(x);
    780   if (mrb_fixnum_p(y)) {
    781     mrb_int b, mod;
    782 
    783     if ((b=mrb_fixnum(y)) == 0) {
     894   if (mrb_fixnum_p(y) && a != MRB_INT_MIN && (b=mrb_fixnum(y)) != MRB_INT_MIN) {
     895    mrb_int mod;
     896
     897    if (b == 0) {
     898#ifdef MRB_WITHOUT_FLOAT
     899      /* ZeroDivisionError */
     900      return mrb_fixnum_value(0);
     901#else
     902      if (a > 0) return mrb_float_value(mrb, INFINITY);
     903      if (a < 0) return mrb_float_value(mrb, INFINITY);
    784904      return mrb_float_value(mrb, NAN);
    785     }
    786     fixdivmod(mrb, a, b, 0, &mod);
     905#endif
     906    }
     907    fixdivmod(mrb, a, b, NULL, &mod);
    787908    return mrb_fixnum_value(mod);
    788909  }
     910#ifdef MRB_WITHOUT_FLOAT
     911  mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     912#else
    789913  else {
    790914    mrb_float mod;
    791915
    792     flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod);
     916    flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), NULL, &mod);
    793917    return mrb_float_value(mrb, mod);
    794918  }
     919#endif
    795920}
    796921
     
    812937
    813938    if (mrb_fixnum(y) == 0) {
    814       return mrb_assoc_new(mrb, mrb_float_value(mrb, INFINITY),
    815         mrb_float_value(mrb, NAN));
     939#ifdef MRB_WITHOUT_FLOAT
     940      return mrb_assoc_new(mrb, mrb_fixnum_value(0), mrb_fixnum_value(0));
     941#else
     942      return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ?
     943                                 mrb_float_value(mrb, NAN):
     944                                 mrb_float_value(mrb, INFINITY)),
     945                           mrb_float_value(mrb, NAN));
     946#endif
    816947    }
    817948    fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod);
    818949    return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod));
    819950  }
     951#ifdef MRB_WITHOUT_FLOAT
     952  mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     953#else
    820954  else {
    821955    mrb_float div, mod;
     
    823957
    824958    flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod);
    825     a = mrb_float_value(mrb, (mrb_int)div);
     959    a = mrb_int_value(mrb, div);
    826960    b = mrb_float_value(mrb, mod);
    827961    return mrb_assoc_new(mrb, a, b);
    828962  }
    829 }
    830 
     963#endif
     964}
     965
     966#ifndef MRB_WITHOUT_FLOAT
    831967static mrb_value
    832968flo_divmod(mrb_state *mrb, mrb_value x)
     
    839975
    840976  flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod);
    841   a = mrb_float_value(mrb, (mrb_int)div);
     977  a = mrb_int_value(mrb, div);
    842978  b = mrb_float_value(mrb, mod);
    843979  return mrb_assoc_new(mrb, a, b);
    844980}
     981#endif
    845982
    846983/* 15.2.8.3.7  */
     
    8651002  case MRB_TT_FIXNUM:
    8661003    return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
     1004#ifndef MRB_WITHOUT_FLOAT
    8671005  case MRB_TT_FLOAT:
    8681006    return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y));
     1007#endif
    8691008  default:
    8701009    return mrb_false_value();
     
    8911030}
    8921031
     1032#ifdef MRB_WITHOUT_FLOAT
     1033#define bit_op(x,y,op1,op2) do {\
     1034  return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
     1035} while(0)
     1036#else
    8931037static mrb_value flo_and(mrb_state *mrb, mrb_value x);
    8941038static mrb_value flo_or(mrb_state *mrb, mrb_value x);
     
    8961040#define bit_op(x,y,op1,op2) do {\
    8971041  if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
    898   return flo_ ## op1(mrb, mrb_float_value(mrb, mrb_fixnum(x)));\
     1042  return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_fixnum(x)));\
    8991043} while(0)
     1044#endif
    9001045
    9011046/* 15.2.8.3.9  */
     
    9561101{
    9571102  if (width < 0) {              /* mrb_int overflow */
     1103#ifdef MRB_WITHOUT_FLOAT
     1104    return mrb_fixnum_value(0);
     1105#else
    9581106    return mrb_float_value(mrb, INFINITY);
     1107#endif
    9591108  }
    9601109  if (val > 0) {
    9611110    if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
    9621111        (val   > (MRB_INT_MAX >> width))) {
     1112#ifdef MRB_WITHOUT_FLOAT
     1113      return mrb_fixnum_value(-1);
     1114#else
    9631115      goto bit_overflow;
    964     }
     1116#endif
     1117    }
     1118    return mrb_fixnum_value(val << width);
    9651119  }
    9661120  else {
    9671121    if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
    968         (val   < (MRB_INT_MIN >> width))) {
     1122        (val   <= (MRB_INT_MIN >> width))) {
     1123#ifdef MRB_WITHOUT_FLOAT
     1124      return mrb_fixnum_value(0);
     1125#else
    9691126      goto bit_overflow;
    970     }
    971   }
    972 
    973   return mrb_fixnum_value(val << width);
    974 
     1127#endif
     1128    }
     1129    return mrb_fixnum_value(val * ((mrb_int)1 << width));
     1130  }
     1131
     1132#ifndef MRB_WITHOUT_FLOAT
    9751133bit_overflow:
    9761134  {
     
    9811139    return mrb_float_value(mrb, f);
    9821140  }
     1141#endif
    9831142}
    9841143
     
    10571216 */
    10581217
     1218#ifndef MRB_WITHOUT_FLOAT
    10591219static mrb_value
    10601220fix_to_f(mrb_state *mrb, mrb_value num)
     
    10701230 *  to numerical classes which don't support them.
    10711231 *
    1072  *     Float::INFINITY.to_r
     1232 *     Float::INFINITY.to_i
    10731233 *
    10741234 *  <em>raises the exception:</em>
     
    10891249    mrb_float d = mrb_float(x);
    10901250
    1091     if (isinf(d)) {
    1092       mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity");
    1093     }
    1094     if (isnan(d)) {
    1095       mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
    1096     }
     1251    mrb_check_num_exact(mrb, d);
    10971252    if (FIXABLE_FLOAT(d)) {
    10981253      z = (mrb_int)d;
    10991254    }
    11001255    else {
    1101       mrb_raisef(mrb, E_ARGUMENT_ERROR, "number (%S) too big for integer", x);
     1256      mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x);
    11021257    }
    11031258  }
    11041259  return mrb_fixnum_value(z);
    11051260}
    1106 
    1107 mrb_value
    1108 mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
     1261#endif
     1262
     1263static mrb_value
     1264fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
    11091265{
    11101266  mrb_int a;
     
    11171273    b = mrb_fixnum(y);
    11181274    if (mrb_int_add_overflow(a, b, &c)) {
     1275#ifndef MRB_WITHOUT_FLOAT
    11191276      return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b);
     1277#endif
    11201278    }
    11211279    return mrb_fixnum_value(c);
    11221280  }
     1281#ifdef MRB_WITHOUT_FLOAT
     1282  mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     1283#else
    11231284  return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y));
     1285#endif
     1286}
     1287
     1288MRB_API mrb_value
     1289mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y)
     1290{
     1291  if (mrb_fixnum_p(x)) {
     1292    return fixnum_plus(mrb, x, y);
     1293  }
     1294#ifndef MRB_WITHOUT_FLOAT
     1295  if (mrb_float_p(x)) {
     1296    return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
     1297  }
     1298#endif
     1299  mrb_raise(mrb, E_TYPE_ERROR, "no number addition");
     1300  return mrb_nil_value();       /* not reached */
    11241301}
    11251302
     
    11391316
    11401317  mrb_get_args(mrb, "o", &other);
    1141   return mrb_fixnum_plus(mrb, self, other);
    1142 }
    1143 
    1144 mrb_value
    1145 mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
     1318  return fixnum_plus(mrb, self, other);
     1319}
     1320
     1321static mrb_value
     1322fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
    11461323{
    11471324  mrb_int a;
     
    11531330    b = mrb_fixnum(y);
    11541331    if (mrb_int_sub_overflow(a, b, &c)) {
     1332#ifndef MRB_WITHOUT_FLOAT
    11551333      return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b);
     1334#endif
    11561335    }
    11571336    return mrb_fixnum_value(c);
    11581337  }
     1338#ifdef MRB_WITHOUT_FLOAT
     1339  mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
     1340#else
    11591341  return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y));
     1342#endif
     1343}
     1344
     1345MRB_API mrb_value
     1346mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y)
     1347{
     1348  if (mrb_fixnum_p(x)) {
     1349    return fixnum_minus(mrb, x, y);
     1350  }
     1351#ifndef MRB_WITHOUT_FLOAT
     1352  if (mrb_float_p(x)) {
     1353    return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y));
     1354  }
     1355#endif
     1356  mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction");
     1357  return mrb_nil_value();       /* not reached */
    11601358}
    11611359
     
    11761374
    11771375  mrb_get_args(mrb, "o", &other);
    1178   return mrb_fixnum_minus(mrb, self, other);
     1376  return fixnum_minus(mrb, self, other);
    11791377}
    11801378
    11811379
    11821380MRB_API mrb_value
    1183 mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)
     1381mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
    11841382{
    11851383  char buf[MRB_INT_BIT+1];
     
    11881386
    11891387  if (base < 2 || 36 < base) {
    1190     mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base));
     1388    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base);
    11911389  }
    11921390
     
    12321430  mrb_get_args(mrb, "|i", &base);
    12331431  return mrb_fixnum_to_str(mrb, self, base);
     1432}
     1433
     1434/* compare two numbers: (1:0:-1; -2 for error) */
     1435static mrb_int
     1436cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2)
     1437{
     1438#ifdef MRB_WITHOUT_FLOAT
     1439  mrb_int x, y;
     1440#else
     1441  mrb_float x, y;
     1442#endif
     1443
     1444#ifdef MRB_WITHOUT_FLOAT
     1445  x = mrb_fixnum(v1);
     1446#else
     1447  x = mrb_to_flo(mrb, v1);
     1448#endif
     1449  switch (mrb_type(v2)) {
     1450  case MRB_TT_FIXNUM:
     1451#ifdef MRB_WITHOUT_FLOAT
     1452    y = mrb_fixnum(v2);
     1453#else
     1454    y = (mrb_float)mrb_fixnum(v2);
     1455#endif
     1456    break;
     1457#ifndef MRB_WITHOUT_FLOAT
     1458  case MRB_TT_FLOAT:
     1459    y = mrb_float(v2);
     1460    break;
     1461#endif
     1462  default:
     1463    return -2;
     1464  }
     1465  if (x > y)
     1466    return 1;
     1467  else {
     1468    if (x < y)
     1469      return -1;
     1470    return 0;
     1471  }
    12341472}
    12351473
     
    12461484 */
    12471485static mrb_value
    1248 num_cmp(mrb_state *mrb, mrb_value self)
     1486integral_cmp(mrb_state *mrb, mrb_value self)
    12491487{
    12501488  mrb_value other;
    1251   mrb_float x, y;
     1489  mrb_int n;
    12521490
    12531491  mrb_get_args(mrb, "o", &other);
    1254 
    1255   x = mrb_to_flo(mrb, self);
    1256   switch (mrb_type(other)) {
     1492  n = cmpnum(mrb, self, other);
     1493  if (n == -2) return mrb_nil_value();
     1494  return mrb_fixnum_value(n);
     1495}
     1496
     1497static mrb_noreturn void
     1498cmperr(mrb_state *mrb, mrb_value v1, mrb_value v2)
     1499{
     1500  mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %t with %t failed", v1, v2);
     1501}
     1502
     1503static mrb_value
     1504integral_lt(mrb_state *mrb, mrb_value self)
     1505{
     1506  mrb_value other;
     1507  mrb_int n;
     1508
     1509  mrb_get_args(mrb, "o", &other);
     1510  n = cmpnum(mrb, self, other);
     1511  if (n == -2) cmperr(mrb, self, other);
     1512  if (n < 0) return mrb_true_value();
     1513  return mrb_false_value();
     1514}
     1515
     1516static mrb_value
     1517integral_le(mrb_state *mrb, mrb_value self)
     1518{
     1519  mrb_value other;
     1520  mrb_int n;
     1521
     1522  mrb_get_args(mrb, "o", &other);
     1523  n = cmpnum(mrb, self, other);
     1524  if (n == -2) cmperr(mrb, self, other);
     1525  if (n <= 0) return mrb_true_value();
     1526  return mrb_false_value();
     1527}
     1528
     1529static mrb_value
     1530integral_gt(mrb_state *mrb, mrb_value self)
     1531{
     1532  mrb_value other;
     1533  mrb_int n;
     1534
     1535  mrb_get_args(mrb, "o", &other);
     1536  n = cmpnum(mrb, self, other);
     1537  if (n == -2) cmperr(mrb, self, other);
     1538  if (n > 0) return mrb_true_value();
     1539  return mrb_false_value();
     1540}
     1541
     1542static mrb_value
     1543integral_ge(mrb_state *mrb, mrb_value self)
     1544{
     1545  mrb_value other;
     1546  mrb_int n;
     1547
     1548  mrb_get_args(mrb, "o", &other);
     1549  n = cmpnum(mrb, self, other);
     1550  if (n == -2) cmperr(mrb, self, other);
     1551  if (n >= 0) return mrb_true_value();
     1552  return mrb_false_value();
     1553}
     1554
     1555MRB_API mrb_int
     1556mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
     1557{
     1558  mrb_value v;
     1559
     1560  switch (mrb_type(obj1)) {
    12571561  case MRB_TT_FIXNUM:
    1258     y = (mrb_float)mrb_fixnum(other);
    1259     break;
    12601562  case MRB_TT_FLOAT:
    1261     y = mrb_float(other);
    1262     break;
     1563    return cmpnum(mrb, obj1, obj2);
     1564  case MRB_TT_STRING:
     1565    if (!mrb_string_p(obj2))
     1566      return -2;
     1567    return mrb_str_cmp(mrb, obj1, obj2);
    12631568  default:
    1264     return mrb_nil_value();
    1265   }
    1266   if (x > y)
    1267     return mrb_fixnum_value(1);
    1268   else {
    1269     if (x < y)
    1270       return mrb_fixnum_value(-1);
    1271     return mrb_fixnum_value(0);
    1272   }
     1569    v = mrb_funcall(mrb, obj1, "<=>", 1, obj2);
     1570    if (mrb_nil_p(v) || !mrb_fixnum_p(v))
     1571      return -2;
     1572    return mrb_fixnum(v);
     1573  }
     1574}
     1575
     1576static mrb_value
     1577num_finite_p(mrb_state *mrb, mrb_value self)
     1578{
     1579  return mrb_true_value();
     1580}
     1581
     1582static mrb_value
     1583num_infinite_p(mrb_state *mrb, mrb_value self)
     1584{
     1585  return mrb_false_value();
    12731586}
    12741587
     
    12811594 * and <code>other</code>.
    12821595 */
     1596#ifndef MRB_WITHOUT_FLOAT
    12831597static mrb_value
    12841598flo_plus(mrb_state *mrb, mrb_value x)
     
    12891603  return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
    12901604}
     1605#endif
    12911606
    12921607/* ------------------------------------------------------------------------*/
     
    12941609mrb_init_numeric(mrb_state *mrb)
    12951610{
    1296   struct RClass *numeric, *integer, *fixnum, *fl;
     1611  struct RClass *numeric, *integer, *fixnum, *integral;
     1612#ifndef MRB_WITHOUT_FLOAT
     1613  struct RClass *fl;
     1614#endif
     1615
     1616  integral = mrb_define_module(mrb, "Integral");
     1617  mrb_define_method(mrb, integral,"**",       integral_pow,    MRB_ARGS_REQ(1));
     1618  mrb_define_method(mrb, integral,"/",        integral_div,    MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.6  */
     1619  mrb_define_method(mrb, integral,"quo",      integral_div,    MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
     1620  mrb_define_method(mrb, integral,"div",      integral_idiv,   MRB_ARGS_REQ(1));
     1621  mrb_define_method(mrb, integral,"<=>",      integral_cmp,    MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.1  */
     1622  mrb_define_method(mrb, integral,"<",        integral_lt,     MRB_ARGS_REQ(1));
     1623  mrb_define_method(mrb, integral,"<=",       integral_le,     MRB_ARGS_REQ(1));
     1624  mrb_define_method(mrb, integral,">",        integral_gt,     MRB_ARGS_REQ(1));
     1625  mrb_define_method(mrb, integral,">=",       integral_ge,     MRB_ARGS_REQ(1));
     1626  mrb_define_method(mrb, integral,"__coerce_step_counter", integral_coerce_step_counter, MRB_ARGS_REQ(2));
    12971627
    12981628  /* Numeric Class */
    12991629  numeric = mrb_define_class(mrb, "Numeric",  mrb->object_class);                /* 15.2.7 */
    1300 
    1301   mrb_define_method(mrb, numeric, "**",       num_pow,         MRB_ARGS_REQ(1));
    1302   mrb_define_method(mrb, numeric, "/",        num_div,         MRB_ARGS_REQ(1)); /* 15.2.8.3.4  */
    1303   mrb_define_method(mrb, numeric, "quo",      num_div,         MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
    1304   mrb_define_method(mrb, numeric, "<=>",      num_cmp,         MRB_ARGS_REQ(1)); /* 15.2.9.3.6  */
     1630  mrb_define_method(mrb, numeric, "finite?",  num_finite_p,    MRB_ARGS_NONE());
     1631  mrb_define_method(mrb, numeric, "infinite?",num_infinite_p,  MRB_ARGS_NONE());
    13051632
    13061633  /* Integer Class */
     
    13101637  mrb_define_method(mrb, integer, "to_i",     int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.24 */
    13111638  mrb_define_method(mrb, integer, "to_int",   int_to_i,        MRB_ARGS_NONE());
    1312   mrb_define_method(mrb, integer, "ceil",     int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */
    1313   mrb_define_method(mrb, integer, "floor",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */
    1314   mrb_define_method(mrb, integer, "round",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */
    1315   mrb_define_method(mrb, integer, "truncate", int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */
     1639#ifndef MRB_WITHOUT_FLOAT
     1640  mrb_define_method(mrb, integer, "ceil",     int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.8 (x) */
     1641  mrb_define_method(mrb, integer, "floor",    int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.10 (x) */
     1642  mrb_define_method(mrb, integer, "round",    int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.12 (x) */
     1643  mrb_define_method(mrb, integer, "truncate", int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.15 (x) */
     1644#endif
    13161645
    13171646  /* Fixnum Class */
     
    13291658  mrb_define_method(mrb, fixnum,  ">>",       fix_rshift,      MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */
    13301659  mrb_define_method(mrb, fixnum,  "eql?",     fix_eql,         MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
    1331   mrb_define_method(mrb, fixnum,  "hash",     flo_hash,        MRB_ARGS_NONE()); /* 15.2.8.3.18 */
     1660#ifndef MRB_WITHOUT_FLOAT
    13321661  mrb_define_method(mrb, fixnum,  "to_f",     fix_to_f,        MRB_ARGS_NONE()); /* 15.2.8.3.23 */
    1333   mrb_define_method(mrb, fixnum,  "to_s",     fix_to_s,        MRB_ARGS_NONE()); /* 15.2.8.3.25 */
    1334   mrb_define_method(mrb, fixnum,  "inspect",  fix_to_s,        MRB_ARGS_NONE());
     1662#endif
     1663  mrb_define_method(mrb, fixnum,  "to_s",     fix_to_s,        MRB_ARGS_OPT(1)); /* 15.2.8.3.25 */
     1664  mrb_define_method(mrb, fixnum,  "inspect",  fix_to_s,        MRB_ARGS_OPT(1));
    13351665  mrb_define_method(mrb, fixnum,  "divmod",   fix_divmod,      MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
    13361666
     1667#ifndef MRB_WITHOUT_FLOAT
    13371668  /* Float Class */
    13381669  mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric);                 /* 15.2.9 */
     
    13481679  mrb_define_method(mrb, fl,      "|",         flo_or,         MRB_ARGS_REQ(1));
    13491680  mrb_define_method(mrb, fl,      "^",         flo_xor,        MRB_ARGS_REQ(1));
    1350   mrb_define_method(mrb, fl,      ">>",        flo_lshift,     MRB_ARGS_REQ(1));
    1351   mrb_define_method(mrb, fl,      "<<",        flo_rshift,     MRB_ARGS_REQ(1));
     1681  mrb_define_method(mrb, fl,      ">>",        flo_rshift,     MRB_ARGS_REQ(1));
     1682  mrb_define_method(mrb, fl,      "<<",        flo_lshift,     MRB_ARGS_REQ(1));
    13521683  mrb_define_method(mrb, fl,      "ceil",      flo_ceil,       MRB_ARGS_NONE()); /* 15.2.9.3.8  */
    13531684  mrb_define_method(mrb, fl,      "finite?",   flo_finite_p,   MRB_ARGS_NONE()); /* 15.2.9.3.9  */
     
    13721703  mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN));
    13731704#endif
    1374 }
     1705
     1706  mrb_include_module(mrb, fl, integral);
     1707#endif
     1708}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/object.c

    r331 r439  
    2525    return (mrb_symbol(v1) == mrb_symbol(v2));
    2626
     27#ifndef MRB_WITHOUT_FLOAT
    2728  case MRB_TT_FLOAT:
    2829    return (mrb_float(v1) == mrb_float(v2));
     30#endif
    2931
    3032  default:
     
    8284nil_to_s(mrb_state *mrb, mrb_value obj)
    8385{
    84   return mrb_str_new(mrb, 0, 0);
     86  return mrb_str_new_frozen(mrb, 0, 0);
    8587}
    8688
     
    8890nil_inspect(mrb_state *mrb, mrb_value obj)
    8991{
    90   return mrb_str_new_lit(mrb, "nil");
     92  return mrb_str_new_lit_frozen(mrb, "nil");
    9193}
    9294
     
    149151true_to_s(mrb_state *mrb, mrb_value obj)
    150152{
    151   return mrb_str_new_lit(mrb, "true");
     153  return mrb_str_new_lit_frozen(mrb, "true");
    152154}
    153155
     
    256258false_to_s(mrb_state *mrb, mrb_value obj)
    257259{
    258   return mrb_str_new_lit(mrb, "false");
     260  return mrb_str_new_lit_frozen(mrb, "false");
    259261}
    260262
     
    296298
    297299static mrb_value
    298 inspect_type(mrb_state *mrb, mrb_value val)
    299 {
    300   if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) {
    301     return mrb_inspect(mrb, val);
    302   }
    303   else {
    304     return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val));
    305   }
    306 }
    307 
    308 static mrb_value
    309300convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise)
    310301{
     
    314305  if (!mrb_respond_to(mrb, val, m)) {
    315306    if (raise) {
    316       mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname));
     307      mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into %s", val, tname);
    317308    }
    318309    return mrb_nil_value();
    319310  }
    320311  return mrb_funcall_argv(mrb, val, m, 0, 0);
    321 }
    322 
    323 MRB_API mrb_value
    324 mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)
    325 {
    326   mrb_value v;
    327 
    328   if (mrb_fixnum_p(val)) return val;
    329   v = convert_type(mrb, val, "Integer", method, FALSE);
    330   if (mrb_nil_p(v) || !mrb_fixnum_p(v)) {
    331     return mrb_nil_value();
    332   }
    333   return v;
    334312}
    335313
     
    342320  v = convert_type(mrb, val, tname, method, TRUE);
    343321  if (mrb_type(v) != type) {
    344     mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val,
    345                mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method));
     322    mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%s", val, tname, method);
    346323  }
    347324  return v;
     
    374351  {MRB_TT_SCLASS, "SClass"},
    375352  {MRB_TT_PROC,   "Proc"},
     353#ifndef MRB_WITHOUT_FLOAT
    376354  {MRB_TT_FLOAT,  "Float"},
     355#endif
    377356  {MRB_TT_ARRAY,  "Array"},
    378357  {MRB_TT_HASH,   "Hash"},
     
    406385          etype = "Fixnum";
    407386        }
    408         else if (mrb_type(x) == MRB_TT_SYMBOL) {
     387        else if (mrb_symbol_p(x)) {
    409388          etype = "Symbol";
    410389        }
     
    415394          etype = mrb_obj_classname(mrb, x);
    416395        }
    417         mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
    418                    mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name));
     396        mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
     397                   etype, type->name);
    419398      }
    420399      type++;
    421400    }
    422     mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)",
    423                mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x)));
     401    mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %d (%d given)", t, mrb_type(x));
    424402  }
    425403}
     
    439417mrb_any_to_s(mrb_state *mrb, mrb_value obj)
    440418{
    441   mrb_value str = mrb_str_buf_new(mrb, 20);
     419  mrb_value str = mrb_str_new_capa(mrb, 20);
    442420  const char *cname = mrb_obj_classname(mrb, obj);
    443421
    444422  mrb_str_cat_lit(mrb, str, "#<");
    445423  mrb_str_cat_cstr(mrb, str, cname);
    446   mrb_str_cat_lit(mrb, str, ":");
    447   mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj)));
     424  if (!mrb_immediate_p(obj)) {
     425    mrb_str_cat_lit(mrb, str, ":");
     426    mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj)));
     427  }
    448428  mrb_str_cat_lit(mrb, str, ">");
    449429
     
    502482}
    503483
    504 static mrb_value
    505 mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
    506 {
    507   mrb_value v;
    508 
    509   if (mrb_fixnum_p(val)) return val;
    510   v = convert_type(mrb, val, "Integer", method, TRUE);
    511   if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
    512     mrb_value type = inspect_type(mrb, val);
    513     mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",
    514                type, type, mrb_str_new_cstr(mrb, method), inspect_type(mrb, v));
    515   }
    516   return v;
    517 }
    518 
    519484MRB_API mrb_value
    520485mrb_to_int(mrb_state *mrb, mrb_value val)
    521486{
    522   return mrb_to_integer(mrb, val, "to_int");
    523 }
    524 
    525 MRB_API mrb_value
    526 mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
     487
     488  if (!mrb_fixnum_p(val)) {
     489#ifndef MRB_WITHOUT_FLOAT
     490    if (mrb_float_p(val)) {
     491      return mrb_flo_to_fixnum(mrb, val);
     492    }
     493#endif
     494    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y to Integer", val);
     495  }
     496  return val;
     497}
     498
     499MRB_API mrb_value
     500mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base)
    527501{
    528502  mrb_value tmp;
     
    530504  if (mrb_nil_p(val)) {
    531505    if (base != 0) goto arg_error;
    532       mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
     506    mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
    533507  }
    534508  switch (mrb_type(val)) {
     509#ifndef MRB_WITHOUT_FLOAT
    535510    case MRB_TT_FLOAT:
    536511      if (base != 0) goto arg_error;
    537       else {
    538         mrb_float f = mrb_float(val);
    539         if (FIXABLE_FLOAT(f)) {
    540           break;
    541         }
    542       }
    543512      return mrb_flo_to_fixnum(mrb, val);
     513#endif
    544514
    545515    case MRB_TT_FIXNUM:
     
    563533    mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
    564534  }
    565   tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
    566   if (mrb_nil_p(tmp)) {
    567     return mrb_to_integer(mrb, val, "to_i");
    568   }
    569   return tmp;
     535  /* to raise TypeError */
     536  return mrb_to_int(mrb, val);
    570537}
    571538
     
    576543}
    577544
     545#ifndef MRB_WITHOUT_FLOAT
    578546MRB_API mrb_value
    579547mrb_Float(mrb_state *mrb, mrb_value val)
     
    596564  }
    597565}
     566#endif
     567
     568MRB_API mrb_value
     569mrb_to_str(mrb_state *mrb, mrb_value val)
     570{
     571  return mrb_ensure_string_type(mrb, val);
     572}
     573
     574/* obsolete: use mrb_ensure_string_type() instead */
     575MRB_API mrb_value
     576mrb_string_type(mrb_state *mrb, mrb_value str)
     577{
     578  return mrb_ensure_string_type(mrb, str);
     579}
     580
     581MRB_API mrb_value
     582mrb_ensure_string_type(mrb_state *mrb, mrb_value str)
     583{
     584  if (!mrb_string_p(str)) {
     585    mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to String", str);
     586  }
     587  return str;
     588}
     589
     590MRB_API mrb_value
     591mrb_check_string_type(mrb_state *mrb, mrb_value str)
     592{
     593  if (!mrb_string_p(str)) return mrb_nil_value();
     594  return str;
     595}
     596
     597MRB_API mrb_value
     598mrb_ensure_array_type(mrb_state *mrb, mrb_value ary)
     599{
     600  if (!mrb_array_p(ary)) {
     601    mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Array", ary);
     602  }
     603  return ary;
     604}
     605
     606MRB_API mrb_value
     607mrb_check_array_type(mrb_state *mrb, mrb_value ary)
     608{
     609  if (!mrb_array_p(ary)) return mrb_nil_value();
     610  return ary;
     611}
     612
     613MRB_API mrb_value
     614mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash)
     615{
     616  if (!mrb_hash_p(hash)) {
     617    mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Hash", hash);
     618  }
     619  return hash;
     620}
     621
     622MRB_API mrb_value
     623mrb_check_hash_type(mrb_state *mrb, mrb_value hash)
     624{
     625  if (!mrb_hash_p(hash)) return mrb_nil_value();
     626  return hash;
     627}
    598628
    599629MRB_API mrb_value
  • EcnlProtoTool/trunk/mruby-2.1.1/src/pool.c

    r331 r439  
    55*/
    66
    7 #include <stddef.h>
    8 #include <stdint.h>
    97#include <string.h>
    108#include <mruby.h>
     
    2624/* end of configuration section */
    2725
     26/* Disable MSVC warning "C4200: nonstandard extension used: zero-sized array
     27 * in struct/union" when in C++ mode */
     28#ifdef _MSC_VER
     29#pragma warning(push)
     30#pragma warning(disable : 4200)
     31#endif
     32
    2833struct mrb_pool_page {
    2934  struct mrb_pool_page *next;
     
    3338  char page[];
    3439};
     40
     41#ifdef _MSC_VER
     42#pragma warning(pop)
     43#endif
    3544
    3645struct mrb_pool {
  • EcnlProtoTool/trunk/mruby-2.1.1/src/print.c

    r331 r439  
    3232{
    3333  mrb_print_backtrace(mrb);
    34   printstr(mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0), stderr);
    3534}
    3635
  • EcnlProtoTool/trunk/mruby-2.1.1/src/proc.c

    r331 r439  
    1010#include <mruby/opcode.h>
    1111
    12 static mrb_code call_iseq[] = {
    13   MKOP_A(OP_CALL, 0),
     12static const mrb_code call_iseq[] = {
     13  OP_CALL,
    1414};
    1515
    16 struct RProc *
     16struct RProc*
    1717mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
    1818{
     
    2121
    2222  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
    23   p->target_class = 0;
    2423  if (ci) {
    25     if (ci->proc)
    26       p->target_class = ci->proc->target_class;
    27     if (!p->target_class)
    28       p->target_class = ci->target_class;
     24    struct RClass *tc = NULL;
     25
     26    if (ci->proc) {
     27      tc = MRB_PROC_TARGET_CLASS(ci->proc);
     28    }
     29    if (tc == NULL) {
     30      tc = ci->target_class;
     31    }
     32    p->upper = ci->proc;
     33    p->e.target_class = tc;
    2934  }
    3035  p->body.irep = irep;
    31   p->env = 0;
    3236  mrb_irep_incref(mrb, irep);
    3337
     
    3640
    3741static struct REnv*
    38 env_new(mrb_state *mrb, int nlocals)
     42env_new(mrb_state *mrb, mrb_int nlocals)
    3943{
    4044  struct REnv *e;
    41 
    42   e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env);
    43   MRB_SET_ENV_STACK_LEN(e, nlocals);
    44   e->cxt.c = mrb->c;
    45   e->cioff = mrb->c->ci - mrb->c->cibase;
     45  mrb_callinfo *ci = mrb->c->ci;
     46  int bidx;
     47
     48  e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
     49  MRB_ENV_SET_STACK_LEN(e, nlocals);
     50  bidx = ci->argc;
     51  if (ci->argc < 0) bidx = 2;
     52  else bidx += 1;
     53  MRB_ENV_SET_BIDX(e, bidx);
     54  e->mid = ci->mid;
    4655  e->stack = mrb->c->stack;
     56  e->cxt = mrb->c;
    4757
    4858  return e;
     
    5060
    5161static void
    52 closure_setup(mrb_state *mrb, struct RProc *p, int nlocals)
    53 {
    54   struct REnv *e;
    55 
    56   if (!mrb->c->ci->env) {
    57     e = env_new(mrb, nlocals);
    58     mrb->c->ci->env = e;
    59   }
    60   else {
    61     e = mrb->c->ci->env;
    62   }
    63   p->env = e;
    64   mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env);
    65 }
    66 
    67 struct RProc *
     62closure_setup(mrb_state *mrb, struct RProc *p)
     63{
     64  mrb_callinfo *ci = mrb->c->ci;
     65  struct RProc *up = p->upper;
     66  struct REnv *e = NULL;
     67
     68  if (ci && ci->env) {
     69    e = ci->env;
     70  }
     71  else if (up) {
     72    struct RClass *tc = MRB_PROC_TARGET_CLASS(p);
     73
     74    e = env_new(mrb, up->body.irep->nlocals);
     75    ci->env = e;
     76    if (tc) {
     77      e->c = tc;
     78      mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc);
     79    }
     80    if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) {
     81      e->mid = MRB_PROC_ENV(up)->mid;
     82    }
     83  }
     84  if (e) {
     85    p->e.env = e;
     86    p->flags |= MRB_PROC_ENVSET;
     87    mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)e);
     88  }
     89}
     90
     91struct RProc*
    6892mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
    6993{
    7094  struct RProc *p = mrb_proc_new(mrb, irep);
    7195
    72   closure_setup(mrb, p, mrb->c->ci->proc->body.irep->nlocals);
     96  closure_setup(mrb, p);
    7397  return p;
    7498}
    7599
    76 MRB_API struct RProc *
     100MRB_API struct RProc*
    77101mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
    78102{
     
    81105  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
    82106  p->body.func = func;
    83   p->flags |= MRB_PROC_CFUNC;
    84   p->env = 0;
     107  p->flags |= MRB_PROC_CFUNC_FL;
     108  p->upper = 0;
     109  p->e.target_class = 0;
    85110
    86111  return p;
    87112}
    88113
    89 MRB_API struct RProc *
     114MRB_API struct RProc*
    90115mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv)
    91116{
     
    94119  int i;
    95120
    96   p->env = e = env_new(mrb, argc);
    97   mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env);
     121  p->e.env = e = env_new(mrb, argc);
     122  p->flags |= MRB_PROC_ENVSET;
     123  mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)e);
    98124  MRB_ENV_UNSHARE_STACK(e);
    99125  e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
     
    111137}
    112138
    113 MRB_API struct RProc *
     139MRB_API struct RProc*
    114140mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals)
    115141{
     
    121147{
    122148  struct RProc *p = mrb->c->ci->proc;
    123   struct REnv *e = p->env;
    124 
    125   if (!MRB_PROC_CFUNC_P(p)) {
     149  struct REnv *e;
     150
     151  if (!p || !MRB_PROC_CFUNC_P(p)) {
    126152    mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc.");
    127153  }
     154  e = MRB_PROC_ENV(p);
    128155  if (!e) {
    129156    mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv.");
    130157  }
    131158  if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) {
    132     mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)",
    133                mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));
     159    mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %i (expected: 0 <= index < %i)",
     160               idx, MRB_ENV_STACK_LEN(e));
    134161  }
    135162
     
    140167mrb_proc_copy(struct RProc *a, struct RProc *b)
    141168{
     169  if (a->body.irep) {
     170    /* already initialized proc */
     171    return;
     172  }
    142173  a->flags = b->flags;
    143174  a->body = b->body;
     
    145176    a->body.irep->refcnt++;
    146177  }
    147   a->target_class = b->target_class;
    148   a->env = b->env;
     178  a->upper = b->upper;
     179  a->e.env = b->e.env;
     180  /* a->e.target_class = a->e.target_class; */
    149181}
    150182
     
    156188  struct RProc *p;
    157189
    158   mrb_get_args(mrb, "&", &blk);
    159   if (mrb_nil_p(blk)) {
    160     /* Calling Proc.new without a block is not implemented yet */
    161     mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
    162   }
     190  /* Calling Proc.new without a block is not implemented yet */
     191  mrb_get_args(mrb, "&!", &blk);
    163192  p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class));
    164193  mrb_proc_copy(p, mrb_proc_ptr(blk));
    165194  proc = mrb_obj_value(p);
    166   mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, blk);
     195  mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, proc);
     196  if (!MRB_PROC_STRICT_P(p) &&
     197      mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].env) {
     198    p->flags |= MRB_PROC_ORPHAN;
     199  }
    167200  return proc;
    168201}
     
    174207
    175208  mrb_get_args(mrb, "o", &proc);
    176   if (mrb_type(proc) != MRB_TT_PROC) {
     209  if (!mrb_proc_p(proc)) {
    177210    mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
    178211  }
     
    181214}
    182215
    183 int
    184 mrb_proc_cfunc_p(struct RProc *p)
    185 {
    186   return MRB_PROC_CFUNC_P(p);
    187 }
    188 
    189 mrb_value
    190 mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self)
    191 {
    192   return (p->body.func)(mrb, self);
    193 }
    194 
    195216/* 15.2.17.4.2 */
    196217static mrb_value
    197 mrb_proc_arity(mrb_state *mrb, mrb_value self)
    198 {
    199   struct RProc *p = mrb_proc_ptr(self);
    200   struct mrb_irep *irep;
    201   mrb_code *iseq;
    202   mrb_aspec aspec;
    203   int ma, op, ra, pa, arity;
    204 
    205   if (MRB_PROC_CFUNC_P(p)) {
    206     /* TODO cfunc aspec not implemented yet */
    207     return mrb_fixnum_value(-1);
    208   }
    209 
    210   irep = p->body.irep;
    211   if (!irep) {
    212     return mrb_fixnum_value(0);
    213   }
    214 
    215   iseq = irep->iseq;
    216   /* arity is depend on OP_ENTER */
    217   if (GET_OPCODE(*iseq) != OP_ENTER) {
    218     return mrb_fixnum_value(0);
    219   }
    220 
    221   aspec = GETARG_Ax(*iseq);
    222   ma = MRB_ASPEC_REQ(aspec);
    223   op = MRB_ASPEC_OPT(aspec);
    224   ra = MRB_ASPEC_REST(aspec);
    225   pa = MRB_ASPEC_POST(aspec);
    226   arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
    227 
    228   return mrb_fixnum_value(arity);
     218proc_arity(mrb_state *mrb, mrb_value self)
     219{
     220  return mrb_fixnum_value(mrb_proc_arity(mrb_proc_ptr(self)));
    229221}
    230222
     
    248240    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
    249241  }
    250   if (mrb_type(blk) != MRB_TT_PROC) {
     242  if (!mrb_proc_p(blk)) {
    251243    mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
    252244  }
     
    261253}
    262254
     255mrb_int
     256mrb_proc_arity(const struct RProc *p)
     257{
     258  struct mrb_irep *irep;
     259  const mrb_code *pc;
     260  mrb_aspec aspec;
     261  int ma, op, ra, pa, arity;
     262
     263  if (MRB_PROC_CFUNC_P(p)) {
     264    /* TODO cfunc aspec not implemented yet */
     265    return -1;
     266  }
     267
     268  irep = p->body.irep;
     269  if (!irep) {
     270    return 0;
     271  }
     272
     273  pc = irep->iseq;
     274  /* arity is depend on OP_ENTER */
     275  if (*pc != OP_ENTER) {
     276    return 0;
     277  }
     278
     279  aspec = PEEK_W(pc+1);
     280  ma = MRB_ASPEC_REQ(aspec);
     281  op = MRB_ASPEC_OPT(aspec);
     282  ra = MRB_ASPEC_REST(aspec);
     283  pa = MRB_ASPEC_POST(aspec);
     284  arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
     285
     286  return arity;
     287}
     288
    263289void
    264290mrb_init_proc(mrb_state *mrb)
    265291{
    266   struct RProc *m;
     292  struct RProc *p;
     293  mrb_method_t m;
    267294  mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
    268295  static const mrb_irep mrb_irep_zero = { 0 };
     
    274301  call_irep->nregs = 2;         /* receiver and block */
    275302
    276   mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_ANY());
     303  mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
    277304  mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1));
    278   mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
    279 
    280   m = mrb_proc_new(mrb, call_irep);
     305  mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE());
     306
     307  p = mrb_proc_new(mrb, call_irep);
     308  MRB_METHOD_FROM_PROC(m, p);
    281309  mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "call"), m);
    282310  mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "[]"), m);
    283311
    284   mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.2.6  */
    285   mrb_define_method(mrb, mrb->kernel_module,       "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.3.27 */
    286 }
     312  mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.2.6  */
     313  mrb_define_method(mrb, mrb->kernel_module,       "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.3.27 */
     314}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/range.c

    r331 r439  
    1111#include <mruby/array.h>
    1212
    13 #define RANGE_CLASS (mrb_class_get(mrb, "Range"))
    14 
    15 MRB_API struct RRange*
    16 mrb_range_ptr(mrb_state *mrb, mrb_value v)
    17 {
    18   struct RRange *r = (struct RRange*)mrb_ptr(v);
    19 
    20   if (r->edges == NULL) {
    21     mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
    22   }
    23   return r;
    24 }
     13#define RANGE_INITIALIZED_MASK 1
     14#define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_MASK)
     15#define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_MASK)
    2516
    2617static void
    27 range_check(mrb_state *mrb, mrb_value a, mrb_value b)
    28 {
    29   mrb_value ans;
     18r_check(mrb_state *mrb, mrb_value a, mrb_value b)
     19{
    3020  enum mrb_vtype ta;
    3121  enum mrb_vtype tb;
     22  mrb_int n;
    3223
    3324  ta = mrb_type(a);
    3425  tb = mrb_type(b);
     26#ifdef MRB_WITHOUT_FLOAT
     27  if (ta == MRB_TT_FIXNUM && tb == MRB_TT_FIXNUM ) {
     28#else
    3529  if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) &&
    3630      (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) {
     31#endif
    3732    return;
    3833  }
    3934
    40   ans =  mrb_funcall(mrb, a, "<=>", 1, b);
    41   if (mrb_nil_p(ans)) {
    42     /* can not be compared */
     35  n = mrb_cmp(mrb, a, b);
     36  if (n == -2) {                /* can not be compared */
    4337    mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
    4438  }
    4539}
    4640
    47 MRB_API mrb_value
    48 mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
    49 {
    50   struct RRange *r;
    51 
    52   range_check(mrb, beg, end);
    53   r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, RANGE_CLASS);
     41static mrb_bool
     42r_le(mrb_state *mrb, mrb_value a, mrb_value b)
     43{
     44  mrb_int n = mrb_cmp(mrb, a, b);
     45
     46  if (n == 0 || n == -1) return TRUE;
     47  return FALSE;
     48}
     49
     50static mrb_bool
     51r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
     52{
     53  return mrb_cmp(mrb, a, b) == 1;
     54}
     55
     56static mrb_bool
     57r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
     58{
     59  mrb_int n = mrb_cmp(mrb, a, b);
     60
     61  if (n == 0 || n == 1) return TRUE;
     62  return FALSE;
     63}
     64
     65static void
     66range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r)
     67{
     68#ifndef MRB_RANGE_EMBED
    5469  r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges));
    55   r->edges->beg = beg;
    56   r->edges->end = end;
    57   r->excl = excl;
    58   return mrb_range_value(r);
     70#endif
     71}
     72
     73static struct RRange *
     74range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl)
     75{
     76  r_check(mrb, beg, end);
     77
     78  if (r) {
     79    if (RANGE_INITIALIZED_P(r)) {
     80      /* Ranges are immutable, so that they should be initialized only once. */
     81      mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "'initialize' called twice");
     82    }
     83    else {
     84      range_ptr_alloc_edges(mrb, r);
     85    }
     86  }
     87  else {
     88    r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class);
     89    range_ptr_alloc_edges(mrb, r);
     90  }
     91
     92  RANGE_BEG(r) = beg;
     93  RANGE_END(r) = end;
     94  RANGE_EXCL(r) = excl;
     95  RANGE_INITIALIZED(r);
     96
     97  return r;
     98}
     99
     100static void
     101range_ptr_replace(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl)
     102{
     103  range_ptr_init(mrb, r, beg, end, excl);
     104  mrb_write_barrier(mrb, (struct RBasic*)r);
    59105}
    60106
     
    66112 *  Returns the first object in <i>rng</i>.
    67113 */
    68 mrb_value
    69 mrb_range_beg(mrb_state *mrb, mrb_value range)
    70 {
    71   struct RRange *r = mrb_range_ptr(mrb, range);
    72 
    73   return r->edges->beg;
     114static mrb_value
     115range_beg(mrb_state *mrb, mrb_value range)
     116{
     117  return mrb_range_beg(mrb, range);
    74118}
    75119
     
    84128 *     (1...10).end   #=> 10
    85129 */
    86 
    87 mrb_value
    88 mrb_range_end(mrb_state *mrb, mrb_value range)
    89 {
    90   struct RRange *r = mrb_range_ptr(mrb, range);
    91 
    92   return r->edges->end;
     130static mrb_value
     131range_end(mrb_state *mrb, mrb_value range)
     132{
     133  return mrb_range_end(mrb, range);
    93134}
    94135
     
    99140 *  Returns <code>true</code> if <i>range</i> excludes its end value.
    100141 */
    101 mrb_value
    102 mrb_range_excl(mrb_state *mrb, mrb_value range)
    103 {
    104   struct RRange *r = mrb_range_ptr(mrb, range);
    105 
    106   return mrb_bool_value(r->excl);
    107 }
    108 
    109 static void
    110 range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end)
    111 {
    112   struct RRange *r = mrb_range_raw_ptr(range);
    113 
    114   range_check(mrb, beg, end);
    115   r->excl = exclude_end;
    116   if (!r->edges) {
    117     r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges));
    118   }
    119   r->edges->beg = beg;
    120   r->edges->end = end;
    121 }
     142static mrb_value
     143range_excl(mrb_state *mrb, mrb_value range)
     144{
     145  return mrb_bool_value(mrb_range_excl_p(mrb, range));
     146}
     147
    122148/*
    123149 *  call-seq:
     
    128154 *  the end object; otherwise, it will be excluded.
    129155 */
    130 
    131 mrb_value
    132 mrb_range_initialize(mrb_state *mrb, mrb_value range)
     156static mrb_value
     157range_initialize(mrb_state *mrb, mrb_value range)
    133158{
    134159  mrb_value beg, end;
    135   mrb_bool exclusive;
    136   int n;
    137 
    138   n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
    139   if (n != 3) {
    140     exclusive = FALSE;
    141   }
    142   /* Ranges are immutable, so that they should be initialized only once. */
    143   if (mrb_range_raw_ptr(range)->edges) {
    144     mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice");
    145   }
    146   range_init(mrb, range, beg, end, exclusive);
     160  mrb_bool exclusive = FALSE;
     161
     162  mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
     163  range_ptr_replace(mrb, mrb_range_raw_ptr(range), beg, end, exclusive);
    147164  return range;
    148165}
     166
    149167/*
    150168 *  call-seq:
     
    159177 *    (0..2) == Range.new(0,2)    #=> true
    160178 *    (0..2) == (0...2)           #=> false
    161  *
    162  */
    163 
    164 mrb_value
    165 mrb_range_eq(mrb_state *mrb, mrb_value range)
     179 */
     180static mrb_value
     181range_eq(mrb_state *mrb, mrb_value range)
    166182{
    167183  struct RRange *rr;
    168184  struct RRange *ro;
    169   mrb_value obj, v1, v2;
     185  mrb_value obj;
     186  mrb_bool v1, v2;
    170187
    171188  mrb_get_args(mrb, "o", &obj);
     
    178195  rr = mrb_range_ptr(mrb, range);
    179196  ro = mrb_range_ptr(mrb, obj);
    180   v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg);
    181   v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end);
    182   if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) {
     197  v1 = mrb_equal(mrb, RANGE_BEG(rr), RANGE_BEG(ro));
     198  v2 = mrb_equal(mrb, RANGE_END(rr), RANGE_END(ro));
     199  if (!v1 || !v2 || RANGE_EXCL(rr) != RANGE_EXCL(ro)) {
    183200    return mrb_false_value();
    184201  }
    185202  return mrb_true_value();
    186 }
    187 
    188 static mrb_bool
    189 r_le(mrb_state *mrb, mrb_value a, mrb_value b)
    190 {
    191   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
    192   /* output :a < b => -1, a = b =>  0, a > b => +1 */
    193 
    194   if (mrb_fixnum_p(r)) {
    195     mrb_int c = mrb_fixnum(r);
    196     if (c == 0 || c == -1) return TRUE;
    197   }
    198 
    199   return FALSE;
    200 }
    201 
    202 static mrb_bool
    203 r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
    204 {
    205   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
    206   /* output :a < b => -1, a = b =>  0, a > b => +1 */
    207 
    208   return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
    209 }
    210 
    211 static mrb_bool
    212 r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
    213 {
    214   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
    215   /* output :a < b => -1, a = b =>  0, a > b => +1 */
    216 
    217   if (mrb_fixnum_p(r)) {
    218     mrb_int c = mrb_fixnum(r);
    219     if (c == 0 || c == 1) return TRUE;
    220   }
    221 
    222   return FALSE;
    223203}
    224204
     
    228208 *     range.member?(val)  =>  true or false
    229209 *     range.include?(val) =>  true or false
    230  *
    231  */
    232 mrb_value
    233 mrb_range_include(mrb_state *mrb, mrb_value range)
     210 */
     211static mrb_value
     212range_include(mrb_state *mrb, mrb_value range)
    234213{
    235214  mrb_value val;
     
    240219  mrb_get_args(mrb, "o", &val);
    241220
    242   beg = r->edges->beg;
    243   end = r->edges->end;
    244   include_p = r_le(mrb, beg, val) &&           /* beg <= val */
    245               (r->excl ? r_gt(mrb, end, val)   /* end >  val */
    246                        : r_ge(mrb, end, val)); /* end >= val */
     221  beg = RANGE_BEG(r);
     222  end = RANGE_END(r);
     223  include_p = r_le(mrb, beg, val) &&                 /* beg <= val */
     224              (RANGE_EXCL(r) ? r_gt(mrb, end, val)   /* end >  val */
     225                             : r_ge(mrb, end, val)); /* end >= val */
    247226
    248227  return mrb_bool_value(include_p);
    249 }
    250 
    251 MRB_API mrb_int
    252 mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
    253 {
    254   mrb_int beg, end;
    255   struct RRange *r;
    256 
    257   if (mrb_type(range) != MRB_TT_RANGE) return 0;
    258   r = mrb_range_ptr(mrb, range);
    259 
    260   beg = mrb_int(mrb, r->edges->beg);
    261   end = mrb_int(mrb, r->edges->end);
    262 
    263   if (beg < 0) {
    264     beg += len;
    265     if (beg < 0) return 2;
    266   }
    267 
    268   if (trunc) {
    269     if (beg > len) return 2;
    270     if (end > len) end = len;
    271   }
    272 
    273   if (end < 0) end += len;
    274   if (!r->excl && (!trunc || end < len))
    275     end++;                      /* include end point */
    276   len = end - beg;
    277   if (len < 0) len = 0;
    278 
    279   *begp = beg;
    280   *lenp = len;
    281   return 1;
    282228}
    283229
     
    289235 * Convert this range object to a printable form.
    290236 */
    291 
    292237static mrb_value
    293238range_to_s(mrb_state *mrb, mrb_value range)
     
    296241  struct RRange *r = mrb_range_ptr(mrb, range);
    297242
    298   str  = mrb_obj_as_string(mrb, r->edges->beg);
    299   str2 = mrb_obj_as_string(mrb, r->edges->end);
     243  str  = mrb_obj_as_string(mrb, RANGE_BEG(r));
     244  str2 = mrb_obj_as_string(mrb, RANGE_END(r));
    300245  str  = mrb_str_dup(mrb, str);
    301   mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
     246  mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
    302247  mrb_str_cat_str(mrb, str, str2);
    303248
     
    314259 * objects).
    315260 */
    316 
    317261static mrb_value
    318262range_inspect(mrb_state *mrb, mrb_value range)
     
    321265  struct RRange *r = mrb_range_ptr(mrb, range);
    322266
    323   str  = mrb_inspect(mrb, r->edges->beg);
    324   str2 = mrb_inspect(mrb, r->edges->end);
     267  str  = mrb_inspect(mrb, RANGE_BEG(r));
     268  str2 = mrb_inspect(mrb, RANGE_END(r));
    325269  str  = mrb_str_dup(mrb, str);
    326   mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
     270  mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
    327271  mrb_str_cat_str(mrb, str, str2);
    328272
     
    342286 *    (0..2).eql?(Range.new(0,2))  #=> true
    343287 *    (0..2).eql?(0...2)           #=> false
    344  *
    345  */
    346 
     288 */
    347289static mrb_value
    348290range_eql(mrb_state *mrb, mrb_value range)
     
    354296
    355297  if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
    356   if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
    357     return mrb_false_value();
    358   }
    359   if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
     298  if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value();
     299  if (!mrb_range_p(obj)) return mrb_false_value();
    360300
    361301  r = mrb_range_ptr(mrb, range);
    362302  o = mrb_range_ptr(mrb, obj);
    363   if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
    364       !mrb_eql(mrb, r->edges->end, o->edges->end) ||
    365       (r->excl != o->excl)) {
     303  if (!mrb_eql(mrb, RANGE_BEG(r), RANGE_BEG(o)) ||
     304      !mrb_eql(mrb, RANGE_END(r), RANGE_END(o)) ||
     305      (RANGE_EXCL(r) != RANGE_EXCL(o))) {
    366306    return mrb_false_value();
    367307  }
     
    384324
    385325  r = mrb_range_ptr(mrb, src);
    386   range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl);
     326  range_ptr_replace(mrb, mrb_range_raw_ptr(copy), RANGE_BEG(r), RANGE_END(r), RANGE_EXCL(r));
    387327
    388328  return copy;
     
    400340      mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i])));
    401341    }
    402     else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) {
     342    else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == MRB_RANGE_OK) {
    403343      mrb_int const end = olen < beg + len ? olen : beg + len;
    404344      for (j = beg; j < end; ++j) {
     
    411351    }
    412352    else {
    413       mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %S", argv[i]);
     353      mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %v", argv[i]);
    414354    }
    415355  }
    416356
    417357  return result;
     358}
     359
     360void
     361mrb_gc_mark_range(mrb_state *mrb, struct RRange *r)
     362{
     363  if (RANGE_INITIALIZED_P(r)) {
     364    mrb_gc_mark_value(mrb, RANGE_BEG(r));
     365    mrb_gc_mark_value(mrb, RANGE_END(r));
     366  }
     367}
     368
     369MRB_API struct RRange*
     370mrb_range_ptr(mrb_state *mrb, mrb_value range)
     371{
     372  struct RRange *r = mrb_range_raw_ptr(range);
     373
     374  /* check for if #initialize_copy was removed [#3320] */
     375  if (!RANGE_INITIALIZED_P(r)) {
     376    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
     377  }
     378  return r;
     379}
     380
     381MRB_API mrb_value
     382mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
     383{
     384  struct RRange *r = range_ptr_init(mrb, NULL, beg, end, excl);
     385  return mrb_range_value(r);
     386}
     387
     388MRB_API enum mrb_range_beg_len
     389mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
     390{
     391  mrb_int beg, end;
     392  struct RRange *r;
     393
     394  if (!mrb_range_p(range)) return MRB_RANGE_TYPE_MISMATCH;
     395  r = mrb_range_ptr(mrb, range);
     396
     397  beg = mrb_int(mrb, RANGE_BEG(r));
     398  end = mrb_int(mrb, RANGE_END(r));
     399
     400  if (beg < 0) {
     401    beg += len;
     402    if (beg < 0) return MRB_RANGE_OUT;
     403  }
     404
     405  if (trunc) {
     406    if (beg > len) return MRB_RANGE_OUT;
     407    if (end > len) end = len;
     408  }
     409
     410  if (end < 0) end += len;
     411  if (!RANGE_EXCL(r) && (!trunc || end < len)) end++;  /* include end point */
     412  len = end - beg;
     413  if (len < 0) len = 0;
     414
     415  *begp = beg;
     416  *lenp = len;
     417  return MRB_RANGE_OK;
    418418}
    419419
     
    424424
    425425  r = mrb_define_class(mrb, "Range", mrb->object_class);                                /* 15.2.14 */
     426  mrb->range_class = r;
    426427  MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE);
    427428
    428   mrb_define_method(mrb, r, "begin",           mrb_range_beg,         MRB_ARGS_NONE()); /* 15.2.14.4.3  */
    429   mrb_define_method(mrb, r, "end",             mrb_range_end,         MRB_ARGS_NONE()); /* 15.2.14.4.5  */
    430   mrb_define_method(mrb, r, "==",              mrb_range_eq,          MRB_ARGS_REQ(1)); /* 15.2.14.4.1  */
    431   mrb_define_method(mrb, r, "===",             mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.2  */
    432   mrb_define_method(mrb, r, "exclude_end?",    mrb_range_excl,        MRB_ARGS_NONE()); /* 15.2.14.4.6  */
    433   mrb_define_method(mrb, r, "first",           mrb_range_beg,         MRB_ARGS_NONE()); /* 15.2.14.4.7  */
    434   mrb_define_method(mrb, r, "include?",        mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.8  */
    435   mrb_define_method(mrb, r, "initialize",      mrb_range_initialize,  MRB_ARGS_ANY());  /* 15.2.14.4.9  */
    436   mrb_define_method(mrb, r, "last",            mrb_range_end,         MRB_ARGS_NONE()); /* 15.2.14.4.10 */
    437   mrb_define_method(mrb, r, "member?",         mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */
    438 
     429  mrb_define_method(mrb, r, "begin",           range_beg,             MRB_ARGS_NONE()); /* 15.2.14.4.3  */
     430  mrb_define_method(mrb, r, "end",             range_end,             MRB_ARGS_NONE()); /* 15.2.14.4.5  */
     431  mrb_define_method(mrb, r, "==",              range_eq,              MRB_ARGS_REQ(1)); /* 15.2.14.4.1  */
     432  mrb_define_method(mrb, r, "===",             range_include,         MRB_ARGS_REQ(1)); /* 15.2.14.4.2  */
     433  mrb_define_method(mrb, r, "exclude_end?",    range_excl,            MRB_ARGS_NONE()); /* 15.2.14.4.6  */
     434  mrb_define_method(mrb, r, "first",           range_beg,             MRB_ARGS_NONE()); /* 15.2.14.4.7  */
     435  mrb_define_method(mrb, r, "include?",        range_include,         MRB_ARGS_REQ(1)); /* 15.2.14.4.8  */
     436  mrb_define_method(mrb, r, "initialize",      range_initialize,      MRB_ARGS_ANY());  /* 15.2.14.4.9  */
     437  mrb_define_method(mrb, r, "last",            range_end,             MRB_ARGS_NONE()); /* 15.2.14.4.10 */
     438  mrb_define_method(mrb, r, "member?",         range_include,         MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */
    439439  mrb_define_method(mrb, r, "to_s",            range_to_s,            MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */
    440440  mrb_define_method(mrb, r, "inspect",         range_inspect,         MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */
  • EcnlProtoTool/trunk/mruby-2.1.1/src/state.c

    r331 r439  
    1212#include <mruby/debug.h>
    1313#include <mruby/string.h>
     14#include <mruby/class.h>
    1415
    1516void mrb_init_core(mrb_state*);
     
    1819void mrb_gc_init(mrb_state*, mrb_gc *gc);
    1920void mrb_gc_destroy(mrb_state*, mrb_gc *gc);
    20 
    21 static mrb_value
    22 inspect_main(mrb_state *mrb, mrb_value mod)
    23 {
    24   return mrb_str_new_lit(mrb, "main");
    25 }
    2621
    2722MRB_API mrb_state*
     
    3227  mrb_state *mrb;
    3328
     29  if (f == NULL) f = mrb_default_allocf;
    3430  mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
    3531  if (mrb == NULL) return NULL;
     
    6258}
    6359
    64 struct alloca_header {
    65   struct alloca_header *next;
    66   char buf[];
    67 };
    68 
    69 MRB_API void*
    70 mrb_alloca(mrb_state *mrb, size_t size)
    71 {
    72   struct alloca_header *p;
    73 
    74   p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
    75   p->next = mrb->mems;
    76   mrb->mems = p;
    77   return (void*)p->buf;
    78 }
    79 
    80 static void
    81 mrb_alloca_free(mrb_state *mrb)
    82 {
    83   struct alloca_header *p;
    84   struct alloca_header *tmp;
    85 
    86   if (mrb == NULL) return;
    87   p = mrb->mems;
    88 
    89   while (p) {
    90     tmp = p;
    91     p = p->next;
    92     mrb_free(mrb, tmp);
    93   }
    94 }
    95 
    9660MRB_API mrb_state*
    9761mrb_open(void)
     
    11276
    11377  if (!disable_gems) {
     78#ifndef DISABLE_GEMS
    11479    mrb_init_mrbgems(mrb);
    11580    mrb_gc_arena_restore(mrb, 0);
     81#endif
    11682  }
    11783  return mrb;
     
    136102
    137103void
     104mrb_irep_cutref(mrb_state *mrb, mrb_irep *irep)
     105{
     106  mrb_irep *tmp;
     107  int i;
     108
     109  for (i=0; i<irep->rlen; i++) {
     110    tmp = irep->reps[i];
     111    irep->reps[i] = NULL;
     112    if (tmp) mrb_irep_decref(mrb, tmp);
     113  }
     114}
     115
     116void
    138117mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
    139118{
    140   size_t i;
     119  int i;
    141120
    142121  if (!(irep->flags & MRB_ISEQ_NO_FREE))
    143     mrb_free(mrb, irep->iseq);
     122    mrb_free(mrb, (void*)irep->iseq);
    144123  if (irep->pool) for (i=0; i<irep->plen; i++) {
    145     if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
     124    if (mrb_string_p(irep->pool[i])) {
    146125      mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
    147126      mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
    148127    }
    149 #ifdef MRB_WORD_BOXING
    150     else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
     128#if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
     129    else if (mrb_float_p(irep->pool[i])) {
    151130      mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
    152131    }
     
    156135  mrb_free(mrb, irep->syms);
    157136  for (i=0; i<irep->rlen; i++) {
    158     mrb_irep_decref(mrb, irep->reps[i]);
     137    if (irep->reps[i])
     138      mrb_irep_decref(mrb, irep->reps[i]);
    159139  }
    160140  mrb_free(mrb, irep->reps);
    161141  mrb_free(mrb, irep->lv);
    162   if (irep->own_filename) {
    163     mrb_free(mrb, (void *)irep->filename);
    164   }
    165   mrb_free(mrb, irep->lines);
    166142  mrb_debug_info_free(mrb, irep->debug_info);
    167143  mrb_free(mrb, irep);
    168 }
    169 
    170 mrb_value
    171 mrb_str_pool(mrb_state *mrb, mrb_value str)
    172 {
    173   struct RString *s = mrb_str_ptr(str);
    174   struct RString *ns;
    175   char *ptr;
    176   mrb_int len;
    177 
    178   ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
    179   ns->tt = MRB_TT_STRING;
    180   ns->c = mrb->string_class;
    181 
    182   if (RSTR_NOFREE_P(s)) {
    183     ns->flags = MRB_STR_NOFREE;
    184     ns->as.heap.ptr = s->as.heap.ptr;
    185     ns->as.heap.len = s->as.heap.len;
    186     ns->as.heap.aux.capa = 0;
    187   }
    188   else {
    189     ns->flags = 0;
    190     if (RSTR_EMBED_P(s)) {
    191       ptr = s->as.ary;
    192       len = RSTR_EMBED_LEN(s);
    193     }
    194     else {
    195       ptr = s->as.heap.ptr;
    196       len = s->as.heap.len;
    197     }
    198 
    199     if (len < RSTRING_EMBED_LEN_MAX) {
    200       RSTR_SET_EMBED_FLAG(ns);
    201       RSTR_SET_EMBED_LEN(ns, len);
    202       if (ptr) {
    203         memcpy(ns->as.ary, ptr, len);
    204       }
    205       ns->as.ary[len] = '\0';
    206     }
    207     else {
    208       ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
    209       ns->as.heap.len = len;
    210       ns->as.heap.aux.capa = len;
    211       if (ptr) {
    212         memcpy(ns->as.heap.ptr, ptr, len);
    213       }
    214       ns->as.heap.ptr[len] = '\0';
    215     }
    216   }
    217   return mrb_obj_value(ns);
    218144}
    219145
     
    246172
    247173  /* free */
     174  mrb_gc_destroy(mrb, &mrb->gc);
     175  mrb_free_context(mrb, mrb->root_c);
    248176  mrb_gc_free_gv(mrb);
    249   mrb_free_context(mrb, mrb->root_c);
    250177  mrb_free_symtbl(mrb);
    251   mrb_alloca_free(mrb);
    252   mrb_gc_destroy(mrb, &mrb->gc);
    253178  mrb_free(mrb, mrb);
    254179}
     
    263188  *irep = mrb_irep_zero;
    264189  irep->refcnt = 1;
    265   irep->own_filename = FALSE;
    266190
    267191  return irep;
     
    271195mrb_top_self(mrb_state *mrb)
    272196{
    273   if (!mrb->top_self) {
    274     mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
    275     mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
    276     mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
    277   }
    278197  return mrb_obj_value(mrb->top_self);
    279198}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/string.c

    r331 r439  
    99#endif
    1010
     11#ifndef MRB_WITHOUT_FLOAT
    1112#include <float.h>
     13#include <math.h>
     14#endif
    1215#include <limits.h>
    1316#include <stddef.h>
     
    1922#include <mruby/range.h>
    2023#include <mruby/string.h>
    21 #include <mruby/re.h>
     24#include <mruby/numeric.h>
    2225
    2326typedef struct mrb_shared_string {
    24   mrb_bool nofree : 1;
    2527  int refcnt;
     28  mrb_ssize capa;
    2629  char *ptr;
    27   mrb_int len;
    2830} mrb_shared_string;
    2931
     
    3133
    3234#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
     35
     36static struct RString*
     37str_init_normal_capa(mrb_state *mrb, struct RString *s,
     38                     const char *p, size_t len, size_t capa)
     39{
     40  char *dst = (char *)mrb_malloc(mrb, capa + 1);
     41  if (p) memcpy(dst, p, len);
     42  dst[len] = '\0';
     43  s->as.heap.ptr = dst;
     44  s->as.heap.len = (mrb_ssize)len;
     45  s->as.heap.aux.capa = (mrb_ssize)capa;
     46  RSTR_UNSET_TYPE_FLAG(s);
     47  return s;
     48}
     49
     50static struct RString*
     51str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len)
     52{
     53  return str_init_normal_capa(mrb, s, p, len, len);
     54}
     55
     56static struct RString*
     57str_init_embed(struct RString *s, const char *p, size_t len)
     58{
     59  if (p) memcpy(RSTR_EMBED_PTR(s), p, len);
     60  RSTR_EMBED_PTR(s)[len] = '\0';
     61  RSTR_SET_TYPE_FLAG(s, EMBED);
     62  RSTR_SET_EMBED_LEN(s, len);
     63  return s;
     64}
     65
     66static struct RString*
     67str_init_nofree(struct RString *s, const char *p, size_t len)
     68{
     69  s->as.heap.ptr = (char *)p;
     70  s->as.heap.len = (mrb_ssize)len;
     71  s->as.heap.aux.capa = 0;             /* nofree */
     72  RSTR_SET_TYPE_FLAG(s, NOFREE);
     73  return s;
     74}
     75
     76static struct RString*
     77str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared)
     78{
     79  if (shared) {
     80    shared->refcnt++;
     81  }
     82  else {
     83    shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
     84    shared->refcnt = 1;
     85    shared->ptr = orig->as.heap.ptr;
     86    shared->capa = orig->as.heap.aux.capa;
     87  }
     88  s->as.heap.ptr = orig->as.heap.ptr;
     89  s->as.heap.len = orig->as.heap.len;
     90  s->as.heap.aux.shared = shared;
     91  RSTR_SET_TYPE_FLAG(s, SHARED);
     92  return s;
     93}
     94
     95static struct RString*
     96str_init_fshared(const struct RString *orig, struct RString *s, struct RString *fshared)
     97{
     98  s->as.heap.ptr = orig->as.heap.ptr;
     99  s->as.heap.len = orig->as.heap.len;
     100  s->as.heap.aux.fshared = fshared;
     101  RSTR_SET_TYPE_FLAG(s, FSHARED);
     102  return s;
     103}
     104
     105static struct RString*
     106str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, size_t len)
     107{
     108  if (RSTR_EMBEDDABLE_P(len)) {
     109    return str_init_embed(s, p, len);
     110  }
     111  else {
     112    return str_init_normal(mrb, s, p, len);
     113  }
     114}
    33115
    34116static struct RString*
    35117str_new_static(mrb_state *mrb, const char *p, size_t len)
    36118{
    37   struct RString *s;
    38 
    39   if (len >= MRB_INT_MAX) {
     119  if (RSTR_EMBEDDABLE_P(len)) {
     120    return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
     121  }
     122  if (len >= MRB_SSIZE_MAX) {
    40123    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
    41124  }
    42   s = mrb_obj_alloc_string(mrb);
    43   s->as.heap.len = len;
    44   s->as.heap.aux.capa = 0;             /* nofree */
    45   s->as.heap.ptr = (char *)p;
    46   s->flags = MRB_STR_NOFREE;
    47 
    48   return s;
     125  return str_init_nofree(mrb_obj_alloc_string(mrb), p, len);
    49126}
    50127
     
    52129str_new(mrb_state *mrb, const char *p, size_t len)
    53130{
     131  if (RSTR_EMBEDDABLE_P(len)) {
     132    return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
     133  }
     134  if (len >= MRB_SSIZE_MAX) {
     135    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
     136  }
     137  if (p && mrb_ro_data_p(p)) {
     138    return str_init_nofree(mrb_obj_alloc_string(mrb), p, len);
     139  }
     140  return str_init_normal(mrb, mrb_obj_alloc_string(mrb), p, len);
     141}
     142
     143static inline void
     144str_with_class(struct RString *s, mrb_value obj)
     145{
     146  s->c = mrb_str_ptr(obj)->c;
     147}
     148
     149static mrb_value
     150mrb_str_new_empty(mrb_state *mrb, mrb_value str)
     151{
     152  struct RString *s = str_new(mrb, 0, 0);
     153
     154  str_with_class(s, str);
     155  return mrb_obj_value(s);
     156}
     157
     158MRB_API mrb_value
     159mrb_str_new_capa(mrb_state *mrb, size_t capa)
     160{
    54161  struct RString *s;
    55162
    56   if (p && mrb_ro_data_p(p)) {
    57     return str_new_static(mrb, p, len);
    58   }
    59   s = mrb_obj_alloc_string(mrb);
    60   if (len < RSTRING_EMBED_LEN_MAX) {
    61     RSTR_SET_EMBED_FLAG(s);
    62     RSTR_SET_EMBED_LEN(s, len);
    63     if (p) {
    64       memcpy(s->as.ary, p, len);
    65     }
     163  if (RSTR_EMBEDDABLE_P(capa)) {
     164    s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0);
     165  }
     166  else if (capa >= MRB_SSIZE_MAX) {
     167    mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big");
     168    /* not reached */
     169    s = NULL;
    66170  }
    67171  else {
    68     if (len >= MRB_INT_MAX) {
    69       mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
    70     }
    71     s->as.heap.len = len;
    72     s->as.heap.aux.capa = len;
    73     s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1);
    74     if (p) {
    75       memcpy(s->as.heap.ptr, p, len);
    76     }
    77   }
    78   RSTR_PTR(s)[len] = '\0';
    79   return s;
    80 }
    81 
    82 static inline void
    83 str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj)
    84 {
    85   s->c = mrb_str_ptr(obj)->c;
    86 }
    87 
    88 static mrb_value
    89 mrb_str_new_empty(mrb_state *mrb, mrb_value str)
    90 {
    91   struct RString *s = str_new(mrb, 0, 0);
    92 
    93   str_with_class(mrb, s, str);
     172    s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa);
     173  }
     174
    94175  return mrb_obj_value(s);
    95176}
     
    102183mrb_str_buf_new(mrb_state *mrb, size_t capa)
    103184{
    104   struct RString *s;
    105 
    106   s = mrb_obj_alloc_string(mrb);
    107 
    108   if (capa >= MRB_INT_MAX) {
    109     mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big");
    110   }
    111185  if (capa < MRB_STR_BUF_MIN_SIZE) {
    112186    capa = MRB_STR_BUF_MIN_SIZE;
    113187  }
    114   s->as.heap.len = 0;
    115   s->as.heap.aux.capa = capa;
    116   s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1);
    117   RSTR_PTR(s)[0] = '\0';
    118 
    119   return mrb_obj_value(s);
     188  return mrb_str_new_capa(mrb, capa);
    120189}
    121190
     
    123192resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
    124193{
    125 #if SIZE_MAX > MRB_INT_MAX
    126     mrb_assert(capacity < MRB_INT_MAX);
     194#if SIZE_MAX > MRB_SSIZE_MAX
     195    mrb_assert(capacity < MRB_SSIZE_MAX);
    127196#endif
    128197  if (RSTR_EMBED_P(s)) {
    129     if (RSTRING_EMBED_LEN_MAX < capacity) {
    130       char *const tmp = (char *)mrb_malloc(mrb, capacity+1);
    131       const mrb_int len = RSTR_EMBED_LEN(s);
    132       memcpy(tmp, s->as.ary, len);
    133       RSTR_UNSET_EMBED_FLAG(s);
    134       s->as.heap.ptr = tmp;
    135       s->as.heap.len = len;
    136       s->as.heap.aux.capa = (mrb_int)capacity;
     198    if (!RSTR_EMBEDDABLE_P(capacity)) {
     199      str_init_normal_capa(mrb, s, RSTR_EMBED_PTR(s), RSTR_EMBED_LEN(s), capacity);
    137200    }
    138201  }
    139202  else {
    140203    s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
    141     s->as.heap.aux.capa = (mrb_int)capacity;
    142   }
    143 }
    144 
    145 static void
    146 str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
    147 {
    148   size_t capa;
    149   size_t total;
    150   ptrdiff_t off = -1;
    151 
    152   if (len == 0) return;
    153   mrb_str_modify(mrb, s);
    154   if (ptr >= RSTR_PTR(s) && ptr <= RSTR_PTR(s) + (size_t)RSTR_LEN(s)) {
    155       off = ptr - RSTR_PTR(s);
    156   }
    157 
    158   capa = RSTR_CAPA(s);
    159   if (capa <= RSTRING_EMBED_LEN_MAX)
    160     capa = RSTRING_EMBED_LEN_MAX+1;
    161 
    162   total = RSTR_LEN(s)+len;
    163   if (total >= MRB_INT_MAX) {
    164   size_error:
    165     mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
    166   }
    167   if (capa <= total) {
    168     while (total > capa) {
    169       if (capa <= MRB_INT_MAX / 2) {
    170         capa *= 2;
    171       }
    172       else {
    173         capa = total;
    174       }
    175     }
    176     if (capa < total || capa > MRB_INT_MAX) {
    177       goto size_error;
    178     }
    179     resize_capa(mrb, s, capa);
    180   }
    181   if (off != -1) {
    182       ptr = RSTR_PTR(s) + off;
    183   }
    184   memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len);
    185   mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX);
    186   RSTR_SET_LEN(s, total);
    187   RSTR_PTR(s)[total] = '\0';   /* sentinel */
     204    s->as.heap.aux.capa = (mrb_ssize)capacity;
     205  }
    188206}
    189207
     
    194212}
    195213
    196 /*
    197  *  call-seq: (Caution! NULL string)
    198  *     String.new(str="")   => new_str
    199  *
    200  *  Returns a new string object containing a copy of <i>str</i>.
    201  */
    202 
    203214MRB_API mrb_value
    204215mrb_str_new_cstr(mrb_state *mrb, const char *p)
     
    231242  shared->refcnt--;
    232243  if (shared->refcnt == 0) {
    233     if (!shared->nofree) {
    234       mrb_free(mrb, shared->ptr);
    235     }
     244    mrb_free(mrb, shared->ptr);
    236245    mrb_free(mrb, shared);
     246  }
     247}
     248
     249static void
     250str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
     251{
     252  if (RSTR_SHARED_P(s)) {
     253    mrb_shared_string *shared = s->as.heap.aux.shared;
     254
     255    if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
     256      s->as.heap.aux.capa = shared->capa;
     257      s->as.heap.ptr[s->as.heap.len] = '\0';
     258      RSTR_UNSET_SHARED_FLAG(s);
     259      mrb_free(mrb, shared);
     260    }
     261    else {
     262      str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len);
     263      str_decref(mrb, shared);
     264    }
     265  }
     266  else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) {
     267    str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len);
     268  }
     269}
     270
     271static void
     272check_null_byte(mrb_state *mrb, mrb_value str)
     273{
     274  mrb_to_str(mrb, str);
     275  if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) {
     276    mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
    237277  }
    238278}
     
    245285  else if (RSTR_SHARED_P(str))
    246286    str_decref(mrb, str->as.heap.aux.shared);
    247   else if (!RSTR_NOFREE_P(str))
     287  else if (!RSTR_NOFREE_P(str) && !RSTR_FSHARED_P(str))
    248288    mrb_free(mrb, str->as.heap.ptr);
    249289}
     
    262302};
    263303
    264 static mrb_int
    265 utf8len(const char* p, const char* e)
     304mrb_int
     305mrb_utf8len(const char* p, const char* e)
    266306{
    267307  mrb_int len;
    268308  mrb_int i;
    269309
     310  if ((unsigned char)*p < 0x80) return 1;
    270311  len = utf8len_codepage[(unsigned char)*p];
    271   if (p + len > e) return 1;
     312  if (len == 1) return 1;
     313  if (len > e - p) return 1;
    272314  for (i = 1; i < len; ++i)
    273315    if ((p[i] & 0xc0) != 0x80)
     
    276318}
    277319
     320mrb_int
     321mrb_utf8_strlen(const char *str, mrb_int byte_len)
     322{
     323  mrb_int total = 0;
     324  const char *p = str;
     325  const char *e = p + byte_len;
     326
     327  while (p < e) {
     328    p += mrb_utf8len(p, e);
     329    total++;
     330  }
     331  return total;
     332}
     333
    278334static mrb_int
    279 utf8_strlen(mrb_value str, mrb_int len)
    280 {
    281   mrb_int total = 0;
    282   char* p = RSTRING_PTR(str);
    283   char* e = p;
    284   if (RSTRING(str)->flags & MRB_STR_NO_UTF) {
    285     return RSTRING_LEN(str);
    286   }
    287   e += len < 0 ? RSTRING_LEN(str) : len;
    288   while (p<e) {
    289     p += utf8len(p, e);
    290     total++;
    291   }
    292   if (RSTRING_LEN(str) == total) {
    293     RSTRING(str)->flags |= MRB_STR_NO_UTF;
    294   }
    295   return total;
    296 }
    297 
    298 #define RSTRING_CHAR_LEN(s) utf8_strlen(s, -1)
     335utf8_strlen(mrb_value str)
     336{
     337  struct RString *s = mrb_str_ptr(str);
     338  mrb_int byte_len = RSTR_LEN(s);
     339
     340  if (RSTR_ASCII_P(s)) {
     341    return byte_len;
     342  }
     343  else {
     344    mrb_int utf8_len = mrb_utf8_strlen(RSTR_PTR(s), byte_len);
     345    if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s);
     346    return utf8_len;
     347  }
     348}
     349
     350#define RSTRING_CHAR_LEN(s) utf8_strlen(s)
    299351
    300352/* map character index to byte offset index */
     
    302354chars2bytes(mrb_value s, mrb_int off, mrb_int idx)
    303355{
    304   mrb_int i, b, n;
    305   const char *p = RSTRING_PTR(s) + off;
    306   const char *e = RSTRING_END(s);
    307 
    308   for (b=i=0; p<e && i<idx; i++) {
    309     n = utf8len(p, e);
    310     b += n;
    311     p += n;
    312   }
    313   return b;
     356  if (RSTR_ASCII_P(mrb_str_ptr(s))) {
     357    return idx;
     358  }
     359  else {
     360    mrb_int i, b, n;
     361    const char *p = RSTRING_PTR(s) + off;
     362    const char *e = RSTRING_END(s);
     363
     364    for (b=i=0; p<e && i<idx; i++) {
     365      n = mrb_utf8len(p, e);
     366      b += n;
     367      p += n;
     368    }
     369    return b;
     370  }
    314371}
    315372
    316373/* map byte offset to character index */
    317374static mrb_int
    318 bytes2chars(char *p, mrb_int bi)
    319 {
    320   mrb_int i, b, n;
    321 
    322   for (b=i=0; b<bi; i++) {
    323     n = utf8len_codepage[(unsigned char)*p];
    324     b += n;
    325     p += n;
    326   }
    327   if (b != bi) return -1;
     375bytes2chars(char *p, mrb_int len, mrb_int bi)
     376{
     377  const char *e = p + (size_t)len;
     378  const char *pivot = p + bi;
     379  mrb_int i;
     380
     381  for (i = 0; p < pivot; i ++) {
     382    p += mrb_utf8len(p, e);
     383  }
     384  if (p != pivot) return -1;
    328385  return i;
     386}
     387
     388static const char *
     389char_adjust(const char *beg, const char *end, const char *ptr)
     390{
     391  if ((ptr > beg || ptr < end) && (*ptr & 0xc0) == 0x80) {
     392    const int utf8_adjust_max = 3;
     393    const char *p;
     394
     395    if (ptr - beg > utf8_adjust_max) {
     396      beg = ptr - utf8_adjust_max;
     397    }
     398
     399    p = ptr;
     400    while (p > beg) {
     401      p --;
     402      if ((*p & 0xc0) != 0x80) {
     403        int clen = mrb_utf8len(p, end);
     404        if (clen > ptr - p) return p;
     405        break;
     406      }
     407    }
     408  }
     409
     410  return ptr;
     411}
     412
     413static const char *
     414char_backtrack(const char *ptr, const char *end)
     415{
     416  if (ptr < end) {
     417    const int utf8_bytelen_max = 4;
     418    const char *p;
     419
     420    if (end - ptr > utf8_bytelen_max) {
     421      ptr = end - utf8_bytelen_max;
     422    }
     423
     424    p = end;
     425    while (p > ptr) {
     426      p --;
     427      if ((*p & 0xc0) != 0x80) {
     428        int clen = utf8len_codepage[(unsigned char)*p];
     429        if (clen == end - p) { return p; }
     430        break;
     431      }
     432    }
     433  }
     434
     435  return end - 1;
     436}
     437
     438static mrb_int
     439str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, const char *s, const mrb_int slen, mrb_int off)
     440{
     441  /* Based on Quick Search algorithm (Boyer-Moore-Horspool algorithm) */
     442
     443  ptrdiff_t qstable[1 << CHAR_BIT];
     444
     445  /* Preprocessing */
     446  {
     447    mrb_int i;
     448
     449    for (i = 0; i < 1 << CHAR_BIT; i ++) {
     450      qstable[i] = slen;
     451    }
     452    for (i = 0; i < slen; i ++) {
     453      qstable[(unsigned char)s[i]] = slen - (i + 1);
     454    }
     455  }
     456
     457  /* Searching */
     458  while (p < pend && pend - p >= slen) {
     459    const char *pivot;
     460
     461    if (memcmp(p, s, slen) == 0) {
     462      return off;
     463    }
     464
     465    pivot = p + qstable[(unsigned char)p[slen - 1]];
     466    if (pivot >= pend || pivot < p /* overflowed */) { return -1; }
     467
     468    do {
     469      p += mrb_utf8len(p, pend);
     470      off ++;
     471    } while (p < pivot);
     472  }
     473
     474  return -1;
     475}
     476
     477static mrb_int
     478str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
     479{
     480  const char *p = RSTRING_PTR(str);
     481  const char *pend = p + RSTRING_LEN(str);
     482  const char *s = RSTRING_PTR(sub);
     483  const mrb_int slen = RSTRING_LEN(sub);
     484  mrb_int off = pos;
     485
     486  for (; pos > 0; pos --) {
     487    if (pend - p < 1) { return -1; }
     488    p += mrb_utf8len(p, pend);
     489  }
     490
     491  if (slen < 1) { return off; }
     492
     493  return str_index_str_by_char_search(mrb, p, pend, s, slen, off);
    329494}
    330495
     
    333498#define RSTRING_CHAR_LEN(s) RSTRING_LEN(s)
    334499#define chars2bytes(p, off, ci) (ci)
    335 #define bytes2chars(p, bi) (bi)
     500#define bytes2chars(p, end, bi) (bi)
     501#define char_adjust(beg, end, ptr) (ptr)
     502#define char_backtrack(ptr, end) ((end) - 1)
    336503#define BYTES_ALIGN_CHECK(pos)
     504#define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos)
     505#endif
     506
     507#ifndef MRB_QS_SHORT_STRING_LENGTH
     508#define MRB_QS_SHORT_STRING_LENGTH 2048
    337509#endif
    338510
     
    340512mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n)
    341513{
    342   const unsigned char *x = xs, *xe = xs + m;
    343   const unsigned char *y = ys;
    344   int i, qstable[256];
    345 
    346   /* Preprocessing */
    347   for (i = 0; i < 256; ++i)
    348     qstable[i] = m + 1;
    349   for (; x < xe; ++x)
    350     qstable[*x] = xe - x;
    351   /* Searching */
    352   for (; y + m <= ys + n; y += *(qstable + y[m])) {
    353     if (*xs == *y && memcmp(xs, y, m) == 0)
    354       return y - ys;
    355   }
    356   return -1;
     514  if (n + m < MRB_QS_SHORT_STRING_LENGTH) {
     515    const unsigned char *y = ys;
     516    const unsigned char *ye = ys+n-m+1;
     517
     518    for (;;) {
     519      y = (const unsigned char*)memchr(y, xs[0], (size_t)(ye-y));
     520      if (y == NULL) return -1;
     521      if (memcmp(xs, y, m) == 0) {
     522        return (mrb_int)(y - ys);
     523      }
     524      y++;
     525    }
     526    return -1;
     527  }
     528  else {
     529    const unsigned char *x = xs, *xe = xs + m;
     530    const unsigned char *y = ys;
     531    int i;
     532    ptrdiff_t qstable[256];
     533
     534    /* Preprocessing */
     535    for (i = 0; i < 256; ++i)
     536      qstable[i] = m + 1;
     537    for (; x < xe; ++x)
     538      qstable[*x] = xe - x;
     539    /* Searching */
     540    for (; y + m <= ys + n; y += *(qstable + y[m])) {
     541      if (*xs == *y && memcmp(xs, y, m) == 0)
     542        return (mrb_int)(y - ys);
     543    }
     544    return -1;
     545  }
    357546}
    358547
     
    373562
    374563    if (ys)
    375       return ys - y;
     564      return (mrb_int)(ys - y);
    376565    else
    377566      return -1;
     
    381570
    382571static void
    383 str_make_shared(mrb_state *mrb, struct RString *s)
    384 {
    385   if (!RSTR_SHARED_P(s)) {
    386     mrb_shared_string *shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
    387 
    388     shared->refcnt = 1;
    389     if (RSTR_EMBED_P(s)) {
    390       const mrb_int len = RSTR_EMBED_LEN(s);
    391       char *const tmp = (char *)mrb_malloc(mrb, len+1);
    392       memcpy(tmp, s->as.ary, len);
    393       tmp[len] = '\0';
    394       RSTR_UNSET_EMBED_FLAG(s);
    395       s->as.heap.ptr = tmp;
    396       s->as.heap.len = len;
    397       shared->nofree = FALSE;
    398       shared->ptr = s->as.heap.ptr;
    399     }
    400     else if (RSTR_NOFREE_P(s)) {
    401       shared->nofree = TRUE;
    402       shared->ptr = s->as.heap.ptr;
    403       RSTR_UNSET_NOFREE_FLAG(s);
    404     }
    405     else {
    406       shared->nofree = FALSE;
    407       if (s->as.heap.aux.capa > s->as.heap.len) {
    408         s->as.heap.ptr = shared->ptr = (char *)mrb_realloc(mrb, s->as.heap.ptr, s->as.heap.len+1);
    409       }
    410       else {
    411         shared->ptr = s->as.heap.ptr;
    412       }
    413     }
    414     shared->len = s->as.heap.len;
    415     s->as.heap.aux.shared = shared;
    416     RSTR_SET_SHARED_FLAG(s);
    417   }
    418 }
    419 
    420 static mrb_value
    421 byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
     572str_share(mrb_state *mrb, struct RString *orig, struct RString *s)
     573{
     574  size_t len = (size_t)orig->as.heap.len;
     575
     576  mrb_assert(!RSTR_EMBED_P(orig));
     577  if (RSTR_NOFREE_P(orig)) {
     578    str_init_nofree(s, orig->as.heap.ptr, len);
     579  }
     580  else if (RSTR_SHARED_P(orig)) {
     581    str_init_shared(mrb, orig, s, orig->as.heap.aux.shared);
     582  }
     583  else if (RSTR_FSHARED_P(orig)) {
     584    str_init_fshared(orig, s, orig->as.heap.aux.fshared);
     585  }
     586  else if (mrb_frozen_p(orig) && !RSTR_POOL_P(orig)) {
     587    str_init_fshared(orig, s, orig);
     588  }
     589  else {
     590    if (orig->as.heap.aux.capa > orig->as.heap.len) {
     591      orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1);
     592      orig->as.heap.aux.capa = (mrb_ssize)len;
     593    }
     594    str_init_shared(mrb, orig, s, NULL);
     595    str_init_shared(mrb, orig, orig, s->as.heap.aux.shared);
     596  }
     597}
     598
     599mrb_value
     600mrb_str_pool(mrb_state *mrb, const char *p, mrb_int len, mrb_bool nofree)
     601{
     602  struct RString *s = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
     603
     604  s->tt = MRB_TT_STRING;
     605  s->c = mrb->string_class;
     606  s->flags = 0;
     607
     608  if (RSTR_EMBEDDABLE_P(len)) {
     609    str_init_embed(s, p, len);
     610  }
     611  else if (nofree) {
     612    str_init_nofree(s, p, len);
     613  }
     614  else {
     615    str_init_normal(mrb, s, p, len);
     616  }
     617  RSTR_SET_POOL_FLAG(s);
     618  MRB_SET_FROZEN_FLAG(s);
     619  return mrb_obj_value(s);
     620}
     621
     622mrb_value
     623mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
    422624{
    423625  struct RString *orig, *s;
    424   mrb_shared_string *shared;
    425626
    426627  orig = mrb_str_ptr(str);
    427   if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) {
    428     s = str_new(mrb, orig->as.ary+beg, len);
     628  s = mrb_obj_alloc_string(mrb);
     629  if (RSTR_EMBEDDABLE_P(len)) {
     630    str_init_embed(s, RSTR_PTR(orig)+beg, len);
    429631  }
    430632  else {
    431     str_make_shared(mrb, orig);
    432     shared = orig->as.heap.aux.shared;
    433     s = mrb_obj_alloc_string(mrb);
    434     s->as.heap.ptr = orig->as.heap.ptr + beg;
    435     s->as.heap.len = len;
    436     s->as.heap.aux.shared = shared;
    437     RSTR_SET_SHARED_FLAG(s);
    438     shared->refcnt++;
    439   }
    440 
     633    str_share(mrb, orig, s);
     634    s->as.heap.ptr += (mrb_ssize)beg;
     635    s->as.heap.len = (mrb_ssize)len;
     636  }
     637  RSTR_COPY_ASCII_FLAG(s, orig);
    441638  return mrb_obj_value(s);
     639}
     640
     641static void
     642str_range_to_bytes(mrb_value str, mrb_int *pos, mrb_int *len)
     643{
     644  *pos = chars2bytes(str, 0, *pos);
     645  *len = chars2bytes(str, *pos, *len);
    442646}
    443647#ifdef MRB_UTF8_STRING
     
    445649str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
    446650{
    447   beg = chars2bytes(str, 0, beg);
    448   len = chars2bytes(str, beg, len);
    449 
    450   return byte_subseq(mrb, str, beg, len);
     651  str_range_to_bytes(str, &beg, &len);
     652  return mrb_str_byte_subseq(mrb, str, beg, len);
    451653}
    452654#else
    453 #define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len)
     655#define str_subseq(mrb, str, beg, len) mrb_str_byte_subseq(mrb, str, beg, len)
    454656#endif
    455657
     658mrb_bool
     659mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp)
     660{
     661  if (str_len < *begp || *lenp < 0) return FALSE;
     662  if (*begp < 0) {
     663    *begp += str_len;
     664    if (*begp < 0) return FALSE;
     665  }
     666  if (*lenp > str_len - *begp)
     667    *lenp = str_len - *begp;
     668  if (*lenp <= 0) {
     669    *lenp = 0;
     670  }
     671  return TRUE;
     672}
     673
    456674static mrb_value
    457675str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
    458676{
    459   mrb_int clen = RSTRING_CHAR_LEN(str);
    460 
    461   if (len < 0) return mrb_nil_value();
    462   if (clen == 0) {
    463     len = 0;
    464   }
    465   else if (beg < 0) {
    466     beg = clen + beg;
    467   }
    468   if (beg > clen) return mrb_nil_value();
    469   if (beg < 0) {
    470     beg += clen;
    471     if (beg < 0) return mrb_nil_value();
    472   }
    473   if (len > clen - beg)
    474     len = clen - beg;
    475   if (len <= 0) {
    476     len = 0;
    477   }
    478   return str_subseq(mrb, str, beg, len);
    479 }
    480 
    481 static mrb_int
    482 str_index(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int offset)
     677  return mrb_str_beg_len(RSTRING_CHAR_LEN(str), &beg, &len) ?
     678    str_subseq(mrb, str, beg, len) : mrb_nil_value();
     679}
     680
     681MRB_API mrb_int
     682mrb_str_index(mrb_state *mrb, mrb_value str, const char *sptr, mrb_int slen, mrb_int offset)
    483683{
    484684  mrb_int pos;
    485   char *s, *sptr;
    486   mrb_int len, slen;
     685  char *s;
     686  mrb_int len;
    487687
    488688  len = RSTRING_LEN(str);
    489   slen = RSTRING_LEN(sub);
    490689  if (offset < 0) {
    491690    offset += len;
     
    499698  if (slen == 0) return offset;
    500699  /* need proceed one character at a time */
    501   sptr = RSTRING_PTR(sub);
    502   slen = RSTRING_LEN(sub);
    503700  len = RSTRING_LEN(str) - offset;
    504701  pos = mrb_memsearch(sptr, slen, s, len);
     
    507704}
    508705
    509 static void
    510 check_frozen(mrb_state *mrb, struct RString *s)
    511 {
    512   if (MRB_FROZEN_P(s)) {
    513     mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string");
    514   }
     706static mrb_int
     707str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset)
     708{
     709  const char *ptr;
     710  mrb_int len;
     711
     712  ptr = RSTRING_PTR(str2);
     713  len = RSTRING_LEN(str2);
     714
     715  return mrb_str_index(mrb, str, ptr, len, offset);
    515716}
    516717
     
    518719str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
    519720{
    520   long len;
    521 
    522   check_frozen(mrb, s1);
     721  size_t len;
     722
     723  mrb_check_frozen(mrb, s1);
    523724  if (s1 == s2) return mrb_obj_value(s1);
    524   s1->flags &= ~MRB_STR_NO_UTF;
    525   s1->flags |= s2->flags&MRB_STR_NO_UTF;
    526   len = RSTR_LEN(s2);
     725  RSTR_COPY_ASCII_FLAG(s1, s2);
    527726  if (RSTR_SHARED_P(s1)) {
    528727    str_decref(mrb, s1->as.heap.aux.shared);
    529728  }
    530   else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1)) {
     729  else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1) && !RSTR_FSHARED_P(s1)
     730           && s1->as.heap.ptr) {
    531731    mrb_free(mrb, s1->as.heap.ptr);
    532732  }
    533733
    534   RSTR_UNSET_NOFREE_FLAG(s1);
    535 
    536   if (RSTR_SHARED_P(s2)) {
    537 L_SHARE:
    538     RSTR_UNSET_EMBED_FLAG(s1);
    539     s1->as.heap.ptr = s2->as.heap.ptr;
    540     s1->as.heap.len = len;
    541     s1->as.heap.aux.shared = s2->as.heap.aux.shared;
    542     RSTR_SET_SHARED_FLAG(s1);
    543     s1->as.heap.aux.shared->refcnt++;
     734  len = (size_t)RSTR_LEN(s2);
     735  if (RSTR_EMBEDDABLE_P(len)) {
     736    str_init_embed(s1, RSTR_PTR(s2), len);
    544737  }
    545738  else {
    546     if (len <= RSTRING_EMBED_LEN_MAX) {
    547       RSTR_UNSET_SHARED_FLAG(s1);
    548       RSTR_SET_EMBED_FLAG(s1);
    549       memcpy(s1->as.ary, RSTR_PTR(s2), len);
    550       RSTR_SET_EMBED_LEN(s1, len);
    551     }
    552     else {
    553       str_make_shared(mrb, s2);
    554       goto L_SHARE;
    555     }
     739    str_share(mrb, s2, s1);
    556740  }
    557741
     
    562746str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
    563747{
    564   char *s, *sbeg, *t;
     748  const char *s, *sbeg, *t;
    565749  struct RString *ps = mrb_str_ptr(str);
    566750  mrb_int len = RSTRING_LEN(sub);
     
    575759  t = RSTRING_PTR(sub);
    576760  if (len) {
     761    s = char_adjust(sbeg, sbeg + RSTR_LEN(ps), s);
    577762    while (sbeg <= s) {
    578763      if (memcmp(s, t, len) == 0) {
    579         return s - RSTR_PTR(ps);
    580       }
    581       s--;
     764        return (mrb_int)(s - RSTR_PTR(ps));
     765      }
     766      s = char_backtrack(sbeg, s);
    582767    }
    583768    return -1;
     
    607792
    608793char*
    609 mrb_utf8_from_locale(const char *str, size_t len)
     794mrb_utf8_from_locale(const char *str, int len)
    610795{
    611796  wchar_t* wcsp;
    612797  char* mbsp;
    613   size_t mbssize, wcssize;
     798  int mbssize, wcssize;
    614799
    615800  if (len == 0)
    616801    return strdup("");
    617802  if (len == -1)
    618     len = strlen(str);
     803    len = (int)strlen(str);
    619804  wcssize = MultiByteToWideChar(GetACP(), 0, str, len,  NULL, 0);
    620805  wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t));
     
    637822
    638823char*
    639 mrb_locale_from_utf8(const char *utf8, size_t len)
     824mrb_locale_from_utf8(const char *utf8, int len)
    640825{
    641826  wchar_t* wcsp;
    642827  char* mbsp;
    643   size_t mbssize, wcssize;
     828  int mbssize, wcssize;
    644829
    645830  if (len == 0)
    646831    return strdup("");
    647832  if (len == -1)
    648     len = strlen(utf8);
     833    len = (int)strlen(utf8);
    649834  wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len,  NULL, 0);
    650835  wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t));
     
    667852
    668853MRB_API void
     854mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
     855{
     856  mrb_check_frozen(mrb, s);
     857  str_modify_keep_ascii(mrb, s);
     858}
     859
     860MRB_API void
    669861mrb_str_modify(mrb_state *mrb, struct RString *s)
    670862{
    671   check_frozen(mrb, s);
    672   s->flags &= ~MRB_STR_NO_UTF;
    673   if (RSTR_SHARED_P(s)) {
    674     mrb_shared_string *shared = s->as.heap.aux.shared;
    675 
    676     if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
    677       s->as.heap.ptr = shared->ptr;
    678       s->as.heap.aux.capa = shared->len;
    679       RSTR_PTR(s)[s->as.heap.len] = '\0';
    680       mrb_free(mrb, shared);
    681     }
    682     else {
    683       char *ptr, *p;
    684       mrb_int len;
    685 
    686       p = RSTR_PTR(s);
    687       len = s->as.heap.len;
    688       if (len < RSTRING_EMBED_LEN_MAX) {
    689         RSTR_SET_EMBED_FLAG(s);
    690         RSTR_SET_EMBED_LEN(s, len);
    691         ptr = RSTR_PTR(s);
    692       }
    693       else {
    694         ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
    695         s->as.heap.ptr = ptr;
    696         s->as.heap.aux.capa = len;
    697       }
    698       if (p) {
    699         memcpy(ptr, p, len);
    700       }
    701       ptr[len] = '\0';
    702       str_decref(mrb, shared);
    703     }
    704     RSTR_UNSET_SHARED_FLAG(s);
    705     return;
    706   }
    707   if (RSTR_NOFREE_P(s)) {
    708     char *p = s->as.heap.ptr;
    709     mrb_int len = s->as.heap.len;
    710 
    711     RSTR_UNSET_NOFREE_FLAG(s);
    712     if (len < RSTRING_EMBED_LEN_MAX) {
    713       RSTR_SET_EMBED_FLAG(s);
    714       RSTR_SET_EMBED_LEN(s, len);
    715     }
    716     else {
    717       s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
    718       s->as.heap.aux.capa = len;
    719     }
    720     if (p) {
    721       memcpy(RSTR_PTR(s), p, len);
    722     }
    723     RSTR_PTR(s)[len] = '\0';
    724     return;
    725   }
     863  mrb_str_modify_keep_ascii(mrb, s);
     864  RSTR_UNSET_ASCII_FLAG(s);
    726865}
    727866
     
    732871  struct RString *s = mrb_str_ptr(str);
    733872
     873  if (len < 0) {
     874    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative (or overflowed) string size");
     875  }
    734876  mrb_str_modify(mrb, s);
    735877  slen = RSTR_LEN(s);
     
    749891  struct RString *s;
    750892
    751   if (!mrb_string_p(str0)) {
    752     mrb_raise(mrb, E_TYPE_ERROR, "expected String");
    753   }
    754 
     893  check_null_byte(mrb, str0);
    755894  s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0));
    756   if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) {
    757     mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
    758   }
    759895  return RSTR_PTR(s);
    760896}
    761897
    762 /*
    763  *  call-seq: (Caution! String("abcd") change)
    764  *     String("abcdefg") = String("abcd") + String("efg")
    765  *
    766  *  Returns a new string object containing a copy of <i>str</i>.
    767  */
    768898MRB_API void
    769899mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other)
    770900{
    771   struct RString *s1 = mrb_str_ptr(self), *s2;
    772   mrb_int len;
    773 
    774   mrb_str_modify(mrb, s1);
    775   if (!mrb_string_p(other)) {
    776     other = mrb_str_to_str(mrb, other);
    777   }
    778   s2 = mrb_str_ptr(other);
    779   if (RSTR_LEN(s2) == 0) {
    780     return;
    781   }
    782   len = RSTR_LEN(s1) + RSTR_LEN(s2);
    783 
    784   if (len < 0 || len >= MRB_INT_MAX) {
    785     mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
    786   }
    787   if (RSTRING_CAPA(self) < len) {
    788     resize_capa(mrb, s1, len);
    789   }
    790   memcpy(RSTR_PTR(s1)+RSTR_LEN(s1), RSTR_PTR(s2), RSTR_LEN(s2));
    791   RSTR_SET_LEN(s1, len);
    792   RSTR_PTR(s1)[len] = '\0';
    793 }
    794 
    795 /*
    796  *  call-seq: (Caution! String("abcd") remain)
    797  *     String("abcdefg") = String("abcd") + String("efg")
    798  *
    799  *  Returns a new string object containing a copy of <i>str</i>.
    800  */
     901  other = mrb_str_to_str(mrb, other);
     902  mrb_str_cat_str(mrb, self, other);
     903}
     904
    801905MRB_API mrb_value
    802906mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b)
     
    816920
    817921/*
    818  *  call-seq: (Caution! String("abcd") remain) for stack_argument
    819  *     String("abcdefg") = String("abcd") + String("efg")
    820  *
    821  *  Returns a new string object containing a copy of <i>str</i>.
     922 *  call-seq:
     923 *     str + other_str   -> new_str
     924 *
     925 *  Concatenation---Returns a new <code>String</code> containing
     926 *  <i>other_str</i> concatenated to <i>str</i>.
     927 *
     928 *     "Hello from " + self.to_s   #=> "Hello from main"
    822929 */
    823930static mrb_value
     
    873980    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
    874981  }
    875   if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) {
     982  if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) {
    876983    mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
    877984  }
     
    879986  len = RSTRING_LEN(self)*times;
    880987  str2 = str_new(mrb, 0, len);
    881   str_with_class(mrb, str2, self);
     988  str_with_class(str2, self);
    882989  p = RSTR_PTR(str2);
    883990  if (len > 0) {
     
    891998  }
    892999  p[RSTR_LEN(str2)] = '\0';
     1000  RSTR_COPY_ASCII_FLAG(str2, mrb_str_ptr(self));
    8931001
    8941002  return mrb_obj_value(str2);
     
    9591067  mrb_get_args(mrb, "o", &str2);
    9601068  if (!mrb_string_p(str2)) {
    961     if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) {
    962       return mrb_nil_value();
    963     }
    964     else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) {
    965       return mrb_nil_value();
    966     }
    967     else {
    968       mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1);
    969 
    970       if (!mrb_nil_p(tmp)) return mrb_nil_value();
    971       if (!mrb_fixnum_p(tmp)) {
    972         return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp);
    973       }
    974       result = -mrb_fixnum(tmp);
    975     }
     1069    return mrb_nil_value();
    9761070  }
    9771071  else {
     
    9951089mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2)
    9961090{
    997   if (mrb_immediate_p(str2)) return FALSE;
    998   if (!mrb_string_p(str2)) {
    999     if (mrb_nil_p(str2)) return FALSE;
    1000     if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_str"))) {
    1001       return FALSE;
    1002     }
    1003     str2 = mrb_funcall(mrb, str2, "to_str", 0);
    1004     return mrb_equal(mrb, str2, str1);
    1005   }
     1091  if (!mrb_string_p(str2)) return FALSE;
    10061092  return str_eql(mrb, str1, str2);
    10071093}
     
    10281114}
    10291115/* ---------------------------------- */
     1116
    10301117MRB_API mrb_value
    10311118mrb_str_to_str(mrb_state *mrb, mrb_value str)
    10321119{
    1033   mrb_value s;
    1034 
    1035   if (!mrb_string_p(str)) {
    1036     s = mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
    1037     if (mrb_nil_p(s)) {
    1038       s = mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s");
    1039     }
    1040     return s;
    1041   }
    1042   return str;
    1043 }
    1044 
     1120  switch (mrb_type(str)) {
     1121  case MRB_TT_STRING:
     1122    return str;
     1123  case MRB_TT_SYMBOL:
     1124    return mrb_sym_str(mrb, mrb_symbol(str));
     1125  case MRB_TT_FIXNUM:
     1126    return mrb_fixnum_to_str(mrb, str, 10);
     1127  case MRB_TT_CLASS:
     1128  case MRB_TT_MODULE:
     1129    return mrb_mod_to_s(mrb, str);
     1130  default:
     1131    return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s");
     1132  }
     1133}
     1134
     1135/* obslete: use RSTRING_PTR() */
    10451136MRB_API const char*
    1046 mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr)
    1047 {
    1048   mrb_value str = mrb_str_to_str(mrb, ptr);
     1137mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
     1138{
     1139  str = mrb_str_to_str(mrb, str);
    10491140  return RSTRING_PTR(str);
    10501141}
    10511142
     1143/* obslete: use RSTRING_LEN() */
    10521144MRB_API mrb_int
    10531145mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
    10541146{
    1055   mrb_value str = mrb_str_to_str(mrb, ptr);
    1056   return RSTRING_LEN(str);
    1057 }
    1058 
    1059 void
    1060 mrb_noregexp(mrb_state *mrb, mrb_value self)
    1061 {
    1062   mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented");
    1063 }
    1064 
    1065 void
    1066 mrb_regexp_check(mrb_state *mrb, mrb_value obj)
    1067 {
    1068   if (mrb_regexp_p(mrb, obj)) {
    1069     mrb_noregexp(mrb, obj);
    1070   }
     1147  mrb_to_str(mrb, ptr);
     1148  return RSTRING_LEN(ptr);
    10711149}
    10721150
     
    10771155  struct RString *dup = str_new(mrb, 0, 0);
    10781156
    1079   str_with_class(mrb, dup, str);
     1157  str_with_class(dup, str);
    10801158  return str_replace(mrb, dup, s);
    10811159}
    10821160
    1083 static mrb_value
    1084 mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
    1085 {
    1086   mrb_int idx;
    1087 
    1088   mrb_regexp_check(mrb, indx);
    1089   switch (mrb_type(indx)) {
    1090     case MRB_TT_FIXNUM:
    1091       idx = mrb_fixnum(indx);
    1092 
    1093 num_index:
    1094       str = str_substr(mrb, str, idx, 1);
    1095       if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
    1096       return str;
    1097 
    1098     case MRB_TT_STRING:
    1099       if (str_index(mrb, str, indx, 0) != -1)
    1100         return mrb_str_dup(mrb, indx);
    1101       return mrb_nil_value();
    1102 
    1103     case MRB_TT_RANGE:
    1104       goto range_arg;
    1105 
    1106     default:
    1107       indx = mrb_Integer(mrb, indx);
    1108       if (mrb_nil_p(indx)) {
    1109       range_arg:
    1110         {
    1111           mrb_int beg, len;
    1112 
    1113           len = RSTRING_CHAR_LEN(str);
    1114           switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) {
    1115           case 1:
    1116             return str_subseq(mrb, str, beg, len);
    1117           case 2:
    1118             return mrb_nil_value();
     1161enum str_convert_range {
     1162  /* `beg` and `len` are byte unit in `0 ... str.bytesize` */
     1163  STR_BYTE_RANGE_CORRECTED = 1,
     1164
     1165  /* `beg` and `len` are char unit in any range */
     1166  STR_CHAR_RANGE = 2,
     1167
     1168  /* `beg` and `len` are char unit in `0 ... str.size` */
     1169  STR_CHAR_RANGE_CORRECTED = 3,
     1170
     1171  /* `beg` is out of range */
     1172  STR_OUT_OF_RANGE = -1
     1173};
     1174
     1175static enum str_convert_range
     1176str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_int *beg, mrb_int *len)
     1177{
     1178  if (!mrb_undef_p(alen)) {
     1179    *beg = mrb_int(mrb, indx);
     1180    *len = mrb_int(mrb, alen);
     1181    return STR_CHAR_RANGE;
     1182  }
     1183  else {
     1184    switch (mrb_type(indx)) {
     1185      case MRB_TT_FIXNUM:
     1186        *beg = mrb_fixnum(indx);
     1187        *len = 1;
     1188        return STR_CHAR_RANGE;
     1189
     1190      case MRB_TT_STRING:
     1191        *beg = str_index_str(mrb, str, indx, 0);
     1192        if (*beg < 0) { break; }
     1193        *len = RSTRING_LEN(indx);
     1194        return STR_BYTE_RANGE_CORRECTED;
     1195
     1196      case MRB_TT_RANGE:
     1197        goto range_arg;
     1198
     1199      default:
     1200        indx = mrb_to_int(mrb, indx);
     1201        if (mrb_fixnum_p(indx)) {
     1202          *beg = mrb_fixnum(indx);
     1203          *len = 1;
     1204          return STR_CHAR_RANGE;
     1205        }
     1206range_arg:
     1207        *len = RSTRING_CHAR_LEN(str);
     1208        switch (mrb_range_beg_len(mrb, indx, beg, len, *len, TRUE)) {
     1209          case MRB_RANGE_OK:
     1210            return STR_CHAR_RANGE_CORRECTED;
     1211          case MRB_RANGE_OUT:
     1212            return STR_OUT_OF_RANGE;
    11191213          default:
    11201214            break;
    1121           }
    11221215        }
     1216
    11231217        mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum");
    1124       }
    1125       idx = mrb_fixnum(indx);
    1126       goto num_index;
    1127   }
    1128   return mrb_nil_value();    /* not reached */
     1218    }
     1219  }
     1220  return STR_OUT_OF_RANGE;
     1221}
     1222
     1223static mrb_value
     1224mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen)
     1225{
     1226  mrb_int beg, len;
     1227
     1228  switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) {
     1229    case STR_CHAR_RANGE_CORRECTED:
     1230      return str_subseq(mrb, str, beg, len);
     1231    case STR_CHAR_RANGE:
     1232      str = str_substr(mrb, str, beg, len);
     1233      if (mrb_undef_p(alen) && !mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
     1234      return str;
     1235    case STR_BYTE_RANGE_CORRECTED:
     1236      if (mrb_string_p(indx)) {
     1237        return mrb_str_dup(mrb, indx);
     1238      }
     1239      else {
     1240        return mrb_str_byte_subseq(mrb, str, beg, len);
     1241      }
     1242    case STR_OUT_OF_RANGE:
     1243    default:
     1244      return mrb_nil_value();
     1245  }
    11291246}
    11301247
     
    11361253 *     str[fixnum, fixnum]         => new_str or nil
    11371254 *     str[range]                  => new_str or nil
    1138  *     str[regexp]                 => new_str or nil
    1139  *     str[regexp, fixnum]         => new_str or nil
    11401255 *     str[other_str]              => new_str or nil
    11411256 *     str.slice(fixnum)           => fixnum or nil
     
    11731288{
    11741289  mrb_value a1, a2;
    1175   int argc;
    1176 
    1177   argc = mrb_get_args(mrb, "o|o", &a1, &a2);
    1178   if (argc == 2) {
    1179     mrb_int n1, n2;
    1180 
    1181     mrb_regexp_check(mrb, a1);
    1182     mrb_get_args(mrb, "ii", &n1, &n2);
    1183     return str_substr(mrb, str, n1, n2);
    1184   }
    1185   if (argc != 1) {
    1186     mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc));
    1187   }
    1188   return mrb_str_aref(mrb, str, a1);
     1290
     1291  if (mrb_get_args(mrb, "o|o", &a1, &a2) == 1) {
     1292    a2 = mrb_undef_value();
     1293  }
     1294
     1295  return mrb_str_aref(mrb, str, a1, a2);
     1296}
     1297
     1298static mrb_noreturn void
     1299str_out_of_index(mrb_state *mrb, mrb_value index)
     1300{
     1301  mrb_raisef(mrb, E_INDEX_ERROR, "index %v out of string", index);
     1302}
     1303
     1304static mrb_value
     1305str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb_value rep)
     1306{
     1307  const mrb_int shrink_threshold = 256;
     1308  struct RString *str = mrb_str_ptr(src);
     1309  mrb_int len = RSTR_LEN(str);
     1310  mrb_int replen, newlen;
     1311  char *strp;
     1312
     1313  if (end > len) { end = len; }
     1314
     1315  if (pos < 0 || pos > len) {
     1316    str_out_of_index(mrb, mrb_fixnum_value(pos));
     1317  }
     1318
     1319  replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep));
     1320  newlen = replen + len - (end - pos);
     1321
     1322  if (newlen >= MRB_SSIZE_MAX || newlen < replen /* overflowed */) {
     1323    mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big");
     1324  }
     1325
     1326  mrb_str_modify(mrb, str);
     1327
     1328  if (len < newlen) {
     1329    resize_capa(mrb, str, newlen);
     1330  }
     1331
     1332  strp = RSTR_PTR(str);
     1333
     1334  memmove(strp + newlen - (len - end), strp + end, len - end);
     1335  if (!mrb_nil_p(rep)) {
     1336    memmove(strp + pos, RSTRING_PTR(rep), replen);
     1337  }
     1338  RSTR_SET_LEN(str, newlen);
     1339  strp[newlen] = '\0';
     1340
     1341  if (len - newlen >= shrink_threshold) {
     1342    resize_capa(mrb, str, newlen);
     1343  }
     1344
     1345  return src;
     1346}
     1347
     1348#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
     1349
     1350static mrb_value
     1351str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect)
     1352{
     1353  const char *p, *pend;
     1354  char buf[4];  /* `\x??` or UTF-8 character */
     1355  mrb_value result = mrb_str_new_lit(mrb, "\"");
     1356#ifdef MRB_UTF8_STRING
     1357  uint32_t ascii_flag = MRB_STR_ASCII;
     1358#endif
     1359
     1360  p = RSTRING_PTR(str); pend = RSTRING_END(str);
     1361  for (;p < pend; p++) {
     1362    unsigned char c, cc;
     1363#ifdef MRB_UTF8_STRING
     1364    if (inspect) {
     1365      mrb_int clen = mrb_utf8len(p, pend);
     1366      if (clen > 1) {
     1367        mrb_int i;
     1368
     1369        for (i=0; i<clen; i++) {
     1370          buf[i] = p[i];
     1371        }
     1372        mrb_str_cat(mrb, result, buf, clen);
     1373        p += clen-1;
     1374        ascii_flag = 0;
     1375        continue;
     1376      }
     1377    }
     1378#endif
     1379    c = *p;
     1380    if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
     1381      buf[0] = '\\'; buf[1] = c;
     1382      mrb_str_cat(mrb, result, buf, 2);
     1383      continue;
     1384    }
     1385    if (ISPRINT(c)) {
     1386      buf[0] = c;
     1387      mrb_str_cat(mrb, result, buf, 1);
     1388      continue;
     1389    }
     1390    switch (c) {
     1391      case '\n': cc = 'n'; break;
     1392      case '\r': cc = 'r'; break;
     1393      case '\t': cc = 't'; break;
     1394      case '\f': cc = 'f'; break;
     1395      case '\013': cc = 'v'; break;
     1396      case '\010': cc = 'b'; break;
     1397      case '\007': cc = 'a'; break;
     1398      case 033: cc = 'e'; break;
     1399      default: cc = 0; break;
     1400    }
     1401    if (cc) {
     1402      buf[0] = '\\';
     1403      buf[1] = (char)cc;
     1404      mrb_str_cat(mrb, result, buf, 2);
     1405      continue;
     1406    }
     1407    else {
     1408      buf[0] = '\\';
     1409      buf[1] = 'x';
     1410      buf[3] = mrb_digitmap[c % 16]; c /= 16;
     1411      buf[2] = mrb_digitmap[c % 16];
     1412      mrb_str_cat(mrb, result, buf, 4);
     1413      continue;
     1414    }
     1415  }
     1416  mrb_str_cat_lit(mrb, result, "\"");
     1417#ifdef MRB_UTF8_STRING
     1418  if (inspect) {
     1419    mrb_str_ptr(str)->flags |= ascii_flag;
     1420    mrb_str_ptr(result)->flags |= ascii_flag;
     1421  }
     1422  else {
     1423    RSTR_SET_ASCII_FLAG(mrb_str_ptr(result));
     1424  }
     1425#endif
     1426
     1427  return result;
     1428}
     1429
     1430static void
     1431mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_value replace)
     1432{
     1433  mrb_int beg, len, charlen;
     1434
     1435  mrb_to_str(mrb, replace);
     1436
     1437  switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) {
     1438    case STR_OUT_OF_RANGE:
     1439    default:
     1440      mrb_raise(mrb, E_INDEX_ERROR, "string not matched");
     1441    case STR_CHAR_RANGE:
     1442      if (len < 0) {
     1443        mrb_raisef(mrb, E_INDEX_ERROR, "negative length %v", alen);
     1444      }
     1445      charlen = RSTRING_CHAR_LEN(str);
     1446      if (beg < 0) { beg += charlen; }
     1447      if (beg < 0 || beg > charlen) { str_out_of_index(mrb, indx); }
     1448      /* fall through */
     1449    case STR_CHAR_RANGE_CORRECTED:
     1450      str_range_to_bytes(str, &beg, &len);
     1451      /* fall through */
     1452    case STR_BYTE_RANGE_CORRECTED:
     1453      str_replace_partial(mrb, str, beg, beg + len, replace);
     1454  }
     1455}
     1456
     1457/*
     1458 * call-seq:
     1459 *    str[fixnum] = replace
     1460 *    str[fixnum, fixnum] = replace
     1461 *    str[range] = replace
     1462 *    str[other_str] = replace
     1463 *
     1464 * Modify +self+ by replacing the content of +self+.
     1465 * The portion of the string affected is determined using the same criteria as +String#[]+.
     1466 */
     1467static mrb_value
     1468mrb_str_aset_m(mrb_state *mrb, mrb_value str)
     1469{
     1470  mrb_value indx, alen, replace;
     1471
     1472  switch (mrb_get_args(mrb, "oo|S!", &indx, &alen, &replace)) {
     1473    case 2:
     1474      replace = alen;
     1475      alen = mrb_undef_value();
     1476      break;
     1477    case 3:
     1478      break;
     1479  }
     1480  mrb_str_aset(mrb, str, indx, alen, replace);
     1481  return str;
    11891482}
    11901483
     
    12091502  struct RString *s = mrb_str_ptr(str);
    12101503
    1211   mrb_str_modify(mrb, s);
     1504  mrb_str_modify_keep_ascii(mrb, s);
    12121505  if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value();
    12131506  p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s);
     
    12671560  struct RString *s = mrb_str_ptr(str);
    12681561
    1269   mrb_str_modify(mrb, s);
    12701562  argc = mrb_get_args(mrb, "|S", &rs);
     1563  mrb_str_modify_keep_ascii(mrb, s);
    12711564  len = RSTR_LEN(s);
    12721565  if (argc == 0) {
     
    13301623 *
    13311624 *  Returns a new <code>String</code> with the given record separator removed
    1332  *  from the end of <i>str</i> (if present). If <code>$/</code> has not been
    1333  *  changed from the default Ruby record separator, then <code>chomp</code> also
    1334  *  removes carriage return characters (that is it will remove <code>\n</code>,
     1625 *  from the end of <i>str</i> (if present). <code>chomp</code> also removes
     1626 *  carriage return characters (that is it will remove <code>\n</code>,
    13351627 *  <code>\r</code>, and <code>\r\n</code>).
    13361628 *
     
    13671659  struct RString *s = mrb_str_ptr(str);
    13681660
    1369   mrb_str_modify(mrb, s);
     1661  mrb_str_modify_keep_ascii(mrb, s);
    13701662  if (RSTR_LEN(s) > 0) {
    13711663    mrb_int len;
     
    13741666    const char* e = p + RSTR_LEN(s);
    13751667    while (p<e) {
    1376       mrb_int clen = utf8len(p, e);
     1668      mrb_int clen = mrb_utf8len(p, e);
    13771669      if (p + clen>=e) break;
    13781670      p += clen;
     
    14361728  struct RString *s = mrb_str_ptr(str);
    14371729
    1438   mrb_str_modify(mrb, s);
     1730  mrb_str_modify_keep_ascii(mrb, s);
    14391731  p = RSTR_PTR(s);
    14401732  pend = RSTR_PTR(s) + RSTR_LEN(s);
     
    15041796
    15051797  mrb_get_args(mrb, "o", &str2);
    1506   eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2);
     1798  eql_p = (mrb_string_p(str2)) && str_eql(mrb, self, str2);
    15071799
    15081800  return mrb_bool_value(eql_p);
     
    15151807}
    15161808
    1517 mrb_int
     1809uint32_t
    15181810mrb_str_hash(mrb_state *mrb, mrb_value str)
    15191811{
     
    15221814  mrb_int len = RSTR_LEN(s);
    15231815  char *p = RSTR_PTR(s);
    1524   mrb_int key = 0;
     1816  uint64_t key = 0;
    15251817
    15261818  while (len--) {
     
    15281820    p++;
    15291821  }
    1530   return key + (key>>5);
     1822  return (uint32_t)(key + (key>>5));
    15311823}
    15321824
     
    15641856
    15651857  mrb_get_args(mrb, "S", &str2);
    1566   if (str_index(mrb, self, str2, 0) < 0)
     1858  if (str_index_str(mrb, self, str2, 0) < 0)
    15671859    return mrb_bool_value(FALSE);
    15681860  return mrb_bool_value(TRUE);
     
    15731865 *  call-seq:
    15741866 *     str.index(substring [, offset])   => fixnum or nil
    1575  *     str.index(fixnum [, offset])      => fixnum or nil
    1576  *     str.index(regexp [, offset])      => fixnum or nil
    15771867 *
    15781868 *  Returns the index of the first occurrence of the given
    1579  *  <i>substring</i>,
    1580  *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>.
    1581  *  Returns
    1582  *  <code>nil</code> if not found.
     1869 *  <i>substring</i>. Returns <code>nil</code> if not found.
    15831870 *  If the second parameter is present, it
    15841871 *  specifies the position in the string to begin the search.
    15851872 *
    1586  *     "hello".index('e')             #=> 1
     1873 *     "hello".index('l')             #=> 2
    15871874 *     "hello".index('lo')            #=> 3
    15881875 *     "hello".index('a')             #=> nil
    1589  *     "hello".index(101)             #=> 1(101=0x65='e')
    1590  *     "hello".index(/[aeiou]/, -3)   #=> 4
    1591  */
    1592 static mrb_value
    1593 mrb_str_index(mrb_state *mrb, mrb_value str)
    1594 {
    1595   mrb_value *argv;
    1596   mrb_int argc;
     1876 *     "hello".index('l', -2)         #=> 3
     1877 */
     1878static mrb_value
     1879mrb_str_index_m(mrb_state *mrb, mrb_value str)
     1880{
    15971881  mrb_value sub;
    1598   mrb_int pos, clen;
    1599 
    1600   mrb_get_args(mrb, "*", &argv, &argc);
    1601   if (argc == 2) {
    1602     mrb_get_args(mrb, "oi", &sub, &pos);
    1603   }
    1604   else {
     1882  mrb_int pos;
     1883
     1884  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
    16051885    pos = 0;
    1606     if (argc > 0)
    1607       sub = argv[0];
    1608     else
    1609       sub = mrb_nil_value();
    1610   }
    1611   mrb_regexp_check(mrb, sub);
    1612   clen = RSTRING_CHAR_LEN(str);
    1613   if (pos < 0) {
     1886  }
     1887  else if (pos < 0) {
     1888    mrb_int clen = RSTRING_CHAR_LEN(str);
    16141889    pos += clen;
    16151890    if (pos < 0) {
     
    16171892    }
    16181893  }
    1619   if (pos > clen) return mrb_nil_value();
    1620   pos = chars2bytes(str, 0, pos);
    1621 
    1622   switch (mrb_type(sub)) {
    1623     default: {
    1624       mrb_value tmp;
    1625 
    1626       tmp = mrb_check_string_type(mrb, sub);
    1627       if (mrb_nil_p(tmp)) {
    1628         mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
    1629       }
    1630       sub = tmp;
    1631     }
    1632     /* fall through */
    1633     case MRB_TT_STRING:
    1634       pos = str_index(mrb, str, sub, pos);
    1635       break;
    1636   }
     1894  pos = str_index_str_by_char(mrb, str, sub, pos);
    16371895
    16381896  if (pos == -1) return mrb_nil_value();
    1639   pos = bytes2chars(RSTRING_PTR(str), pos);
    16401897  BYTES_ALIGN_CHECK(pos);
    16411898  return mrb_fixnum_value(pos);
    16421899}
    1643 
    1644 #define STR_REPLACE_SHARED_MIN 10
    16451900
    16461901/* 15.2.10.5.24 */
     
    17121967mrb_obj_as_string(mrb_state *mrb, mrb_value obj)
    17131968{
    1714   mrb_value str;
    1715 
    17161969  if (mrb_string_p(obj)) {
    17171970    return obj;
    17181971  }
    1719   str = mrb_funcall(mrb, obj, "to_s", 0);
    1720   if (!mrb_string_p(str))
    1721     return mrb_any_to_s(mrb, obj);
    1722   return str;
     1972  return mrb_str_to_str(mrb, obj);
    17231973}
    17241974
     
    17532003}
    17542004
    1755 MRB_API mrb_value
    1756 mrb_string_type(mrb_state *mrb, mrb_value str)
    1757 {
    1758   return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
    1759 }
    1760 
    1761 MRB_API mrb_value
    1762 mrb_check_string_type(mrb_state *mrb, mrb_value str)
    1763 {
    1764   return mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
     2005static inline void
     2006str_reverse(char *p, char *e)
     2007{
     2008  char c;
     2009
     2010  while (p < e) {
     2011    c = *p;
     2012    *p++ = *e;
     2013    *e-- = c;
     2014  }
    17652015}
    17662016
     
    17752025mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
    17762026{
     2027  struct RString *s = mrb_str_ptr(str);
     2028  char *p, *e;
     2029
    17772030#ifdef MRB_UTF8_STRING
    17782031  mrb_int utf8_len = RSTRING_CHAR_LEN(str);
    1779   mrb_int len = RSTRING_LEN(str);
    1780 
    1781   if (utf8_len == len) goto bytes;
    1782   if (utf8_len > 1) {
    1783     char *buf;
    1784     char *p, *e, *r;
    1785 
    1786     mrb_str_modify(mrb, mrb_str_ptr(str));
    1787     len = RSTRING_LEN(str);
    1788     buf = (char*)mrb_malloc(mrb, (size_t)len);
    1789     p = buf;
    1790     e = buf + len;
    1791 
    1792     memcpy(buf, RSTRING_PTR(str), len);
    1793     r = RSTRING_PTR(str) + len;
    1794 
     2032  mrb_int len = RSTR_LEN(s);
     2033
     2034  if (utf8_len < 2) return str;
     2035  if (utf8_len < len) {
     2036    mrb_str_modify(mrb, s);
     2037    p = RSTR_PTR(s);
     2038    e = p + RSTR_LEN(s);
    17952039    while (p<e) {
    1796       mrb_int clen = utf8len(p, e);
    1797       r -= clen;
    1798       memcpy(r, p, clen);
     2040      mrb_int clen = mrb_utf8len(p, e);
     2041      str_reverse(p, p + clen - 1);
    17992042      p += clen;
    18002043    }
    1801     mrb_free(mrb, buf);
     2044    goto bytes;
     2045  }
     2046#endif
     2047
     2048  if (RSTR_LEN(s) > 1) {
     2049    mrb_str_modify(mrb, s);
     2050    goto bytes;
    18022051  }
    18032052  return str;
    18042053
    18052054 bytes:
    1806 #endif
    1807   {
    1808     struct RString *s = mrb_str_ptr(str);
    1809     char *p, *e;
    1810     char c;
    1811 
    1812     mrb_str_modify(mrb, s);
    1813     if (RSTR_LEN(s) > 1) {
    1814       p = RSTR_PTR(s);
    1815       e = p + RSTR_LEN(s) - 1;
    1816       while (p < e) {
    1817       c = *p;
    1818       *p++ = *e;
    1819       *e-- = c;
    1820       }
    1821     }
    1822     return str;
    1823   }
     2055  p = RSTR_PTR(s);
     2056  e = p + RSTR_LEN(s) - 1;
     2057  str_reverse(p, e);
     2058  return str;
    18242059}
    18252060
     
    18452080/*
    18462081 *  call-seq:
    1847  *     str.rindex(substring [, fixnum])   => fixnum or nil
    1848  *     str.rindex(fixnum [, fixnum])   => fixnum or nil
    1849  *     str.rindex(regexp [, fixnum])   => fixnum or nil
    1850  *
    1851  *  Returns the index of the last occurrence of the given <i>substring</i>,
    1852  *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns
    1853  *  <code>nil</code> if not found. If the second parameter is present, it
    1854  *  specifies the position in the string to end the search---characters beyond
    1855  *  this point will not be considered.
     2082 *     str.rindex(substring [, offset])   => fixnum or nil
     2083 *
     2084 *  Returns the index of the last occurrence of the given <i>substring</i>.
     2085 *  Returns <code>nil</code> if not found. If the second parameter is
     2086 *  present, it specifies the position in the string to end the
     2087 *  search---characters beyond this point will not be considered.
    18562088 *
    18572089 *     "hello".rindex('e')             #=> 1
    18582090 *     "hello".rindex('l')             #=> 3
    18592091 *     "hello".rindex('a')             #=> nil
    1860  *     "hello".rindex(101)             #=> 1
    1861  *     "hello".rindex(/[aeiou]/, -2)   #=> 1
     2092 *     "hello".rindex('l', 2)          #=> 2
    18622093 */
    18632094static mrb_value
    18642095mrb_str_rindex(mrb_state *mrb, mrb_value str)
    18652096{
    1866   mrb_value *argv;
    1867   mrb_int argc;
    18682097  mrb_value sub;
    18692098  mrb_int pos, len = RSTRING_CHAR_LEN(str);
    18702099
    1871   mrb_get_args(mrb, "*", &argv, &argc);
    1872   if (argc == 2) {
    1873     mrb_get_args(mrb, "oi", &sub, &pos);
     2100  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
     2101    pos = len;
     2102  }
     2103  else {
    18742104    if (pos < 0) {
    18752105      pos += len;
    18762106      if (pos < 0) {
    1877         mrb_regexp_check(mrb, sub);
    18782107        return mrb_nil_value();
    18792108      }
     
    18812110    if (pos > len) pos = len;
    18822111  }
    1883   else {
    1884     pos = len;
    1885     if (argc > 0)
    1886       sub = argv[0];
    1887     else
    1888       sub = mrb_nil_value();
    1889   }
    18902112  pos = chars2bytes(str, 0, pos);
    1891   mrb_regexp_check(mrb, sub);
    1892 
    1893   switch (mrb_type(sub)) {
    1894     default: {
    1895       mrb_value tmp;
    1896 
    1897       tmp = mrb_check_string_type(mrb, sub);
    1898       if (mrb_nil_p(tmp)) {
    1899         mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
    1900       }
    1901       sub = tmp;
    1902     }
    1903      /* fall through */
    1904     case MRB_TT_STRING:
    1905       pos = str_rindex(mrb, str, sub, pos);
    1906       if (pos >= 0) {
    1907         pos = bytes2chars(RSTRING_PTR(str), pos);
    1908         BYTES_ALIGN_CHECK(pos);
    1909         return mrb_fixnum_value(pos);
    1910       }
    1911       break;
    1912 
    1913   } /* end of switch (TYPE(sub)) */
     2113  pos = str_rindex(mrb, str, sub, pos);
     2114  if (pos >= 0) {
     2115    pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos);
     2116    BYTES_ALIGN_CHECK(pos);
     2117    return mrb_fixnum_value(pos);
     2118  }
    19142119  return mrb_nil_value();
    19152120}
     
    19192124/*
    19202125 *  call-seq:
    1921  *     str.split(pattern="\n", [limit])   => anArray
     2126 *     str.split(separator=nil, [limit])   => anArray
    19222127 *
    19232128 *  Divides <i>str</i> into substrings based on a delimiter, returning an array
    19242129 *  of these substrings.
    19252130 *
    1926  *  If <i>pattern</i> is a <code>String</code>, then its contents are used as
    1927  *  the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single
     2131 *  If <i>separator</i> is a <code>String</code>, then its contents are used as
     2132 *  the delimiter when splitting <i>str</i>. If <i>separator</i> is a single
    19282133 *  space, <i>str</i> is split on whitespace, with leading whitespace and runs
    19292134 *  of contiguous whitespace characters ignored.
    19302135 *
    1931  *  If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the
    1932  *  pattern matches. Whenever the pattern matches a zero-length string,
    1933  *  <i>str</i> is split into individual characters.
    1934  *
    1935  *  If <i>pattern</i> is omitted, the value of <code>$;</code> is used.  If
    1936  *  <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is
    1937  *  split on whitespace as if ' ' were specified.
     2136 *  If <i>separator</i> is omitted or <code>nil</code> (which is the default),
     2137 *  <i>str</i> is split on whitespace as if ' ' were specified.
    19382138 *
    19392139 *  If the <i>limit</i> parameter is omitted, trailing null fields are
     
    19462146 *     " now's  the time".split        #=> ["now's", "the", "time"]
    19472147 *     " now's  the time".split(' ')   #=> ["now's", "the", "time"]
    1948  *     " now's  the time".split(/ /)   #=> ["", "now's", "", "the", "time"]
    1949  *     "hello".split(//)               #=> ["h", "e", "l", "l", "o"]
    1950  *     "hello".split(//, 3)            #=> ["h", "e", "llo"]
    19512148 *
    19522149 *     "mellow yellow".split("ello")   #=> ["m", "w y", "w"]
     
    19592156mrb_str_split_m(mrb_state *mrb, mrb_value str)
    19602157{
    1961   int argc;
     2158  mrb_int argc;
    19622159  mrb_value spat = mrb_nil_value();
    1963   enum {awk, string, regexp} split_type = string;
     2160  enum {awk, string} split_type = string;
    19642161  mrb_int i = 0;
    19652162  mrb_int beg;
     
    19832180    split_type = awk;
    19842181  }
    1985   else {
    1986     if (mrb_string_p(spat)) {
    1987       split_type = string;
    1988       if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
    1989           split_type = awk;
    1990       }
    1991     }
    1992     else {
    1993       mrb_noregexp(mrb, str);
    1994     }
     2182  else if (!mrb_string_p(spat)) {
     2183    mrb_raise(mrb, E_TYPE_ERROR, "expected String");
     2184  }
     2185  else if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
     2186    split_type = awk;
    19952187  }
    19962188
     
    20182210      }
    20192211      else if (ISSPACE(c)) {
    2020         mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg));
     2212        mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, beg, end-beg));
    20212213        mrb_gc_arena_restore(mrb, ai);
    20222214        skip = TRUE;
     
    20292221    }
    20302222  }
    2031   else if (split_type == string) {
     2223  else {                        /* split_type == string */
    20322224    mrb_int str_len = RSTRING_LEN(str);
    20332225    mrb_int pat_len = RSTRING_LEN(spat);
     
    20432235        end = chars2bytes(str, idx, 1);
    20442236      }
    2045       mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end));
     2237      mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, idx, end));
    20462238      mrb_gc_arena_restore(mrb, ai);
    20472239      idx += end + pat_len;
     
    20502242    beg = idx;
    20512243  }
    2052   else {
    2053     mrb_noregexp(mrb, str);
    2054   }
    20552244  if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
    20562245    if (RSTRING_LEN(str) == beg) {
     
    20582247    }
    20592248    else {
    2060       tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
     2249      tmp = mrb_str_byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
    20612250    }
    20622251    mrb_ary_push(mrb, result, tmp);
     
    20722261}
    20732262
    2074 MRB_API mrb_value
    2075 mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, int base, int badcheck)
     2263mrb_value
     2264mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, int badcheck)
    20762265{
    20772266  const char *p = str;
     
    21562345    default:
    21572346      if (base < 2 || 36 < base) {
    2158         mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
     2347        mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
    21592348      }
    21602349      break;
     
    21832372      p--;
    21842373  }
    2185   if (p == pend) {
     2374  if (p == pend || *p == '_') {
    21862375    if (badcheck) goto bad;
    21872376    return mrb_fixnum_value(0);
     
    22092398    n += c;
    22102399    if (n > (uint64_t)MRB_INT_MAX + (sign ? 0 : 1)) {
    2211       mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer",
    2212                  mrb_str_new(mrb, str, pend-str));
     2400#ifndef MRB_WITHOUT_FLOAT
     2401      if (base == 10) {
     2402        return mrb_float_value(mrb, mrb_str_to_dbl(mrb, mrb_str_new(mrb, str, len), badcheck));
     2403      }
     2404      else
     2405#endif
     2406      {
     2407        mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str);
     2408      }
    22132409    }
    22142410  }
    22152411  val = (mrb_int)n;
    22162412  if (badcheck) {
    2217     if (p == str) goto bad; /* no number */
     2413    if (p == str) goto bad;             /* no number */
     2414    if (*(p - 1) == '_') goto bad;      /* trailing '_' */
    22182415    while (p<pend && ISSPACE(*p)) p++;
    2219     if (p<pend) goto bad;       /* trailing garbage */
     2416    if (p<pend) goto bad;               /* trailing garbage */
    22202417  }
    22212418
     
    22252422  /* not reached */
    22262423 bad:
    2227   mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)",
    2228              mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str)));
     2424  mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%!l)", str, pend-str);
    22292425  /* not reached */
    22302426  return mrb_fixnum_value(0);
     
    22322428
    22332429MRB_API mrb_value
    2234 mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
     2430mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badcheck)
    22352431{
    22362432  return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck);
    22372433}
    22382434
     2435/* obslete: use RSTRING_CSTR() or mrb_string_cstr() */
    22392436MRB_API const char*
    22402437mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
    22412438{
    2242   mrb_value str = mrb_str_to_str(mrb, *ptr);
    2243   struct RString *ps = mrb_str_ptr(str);
    2244   mrb_int len = mrb_str_strlen(mrb, ps);
    2245   char *p = RSTR_PTR(ps);
    2246 
    2247   if (!p || p[len] != '\0') {
    2248     if (MRB_FROZEN_P(ps)) {
    2249       *ptr = str = mrb_str_dup(mrb, str);
    2250       ps = mrb_str_ptr(str);
    2251     }
    2252     mrb_str_modify(mrb, ps);
    2253     return RSTR_PTR(ps);
    2254   }
    2255   return p;
     2439  struct RString *ps;
     2440  const char *p;
     2441  mrb_int len;
     2442
     2443  check_null_byte(mrb, *ptr);
     2444  ps = mrb_str_ptr(*ptr);
     2445  p = RSTR_PTR(ps);
     2446  len = RSTR_LEN(ps);
     2447  if (p[len] == '\0') {
     2448    return p;
     2449  }
     2450
     2451  /*
     2452   * Even after str_modify_keep_ascii(), NULL termination is not ensured if
     2453   * RSTR_SET_LEN() is used explicitly (e.g. String#delete_suffix!).
     2454   */
     2455  str_modify_keep_ascii(mrb, ps);
     2456  RSTR_PTR(ps)[len] = '\0';
     2457  return RSTR_PTR(ps);
     2458}
     2459
     2460MRB_API const char*
     2461mrb_string_cstr(mrb_state *mrb, mrb_value str)
     2462{
     2463  return mrb_string_value_cstr(mrb, &str);
    22562464}
    22572465
     
    22622470  mrb_int len;
    22632471
    2264   s = mrb_string_value_ptr(mrb, str);
     2472  mrb_to_str(mrb, str);
     2473  s = RSTRING_PTR(str);
    22652474  len = RSTRING_LEN(str);
    22662475  return mrb_str_len_to_inum(mrb, s, len, base, badcheck);
     
    22952504  mrb_get_args(mrb, "|i", &base);
    22962505  if (base < 0) {
    2297     mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
     2506    mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
    22982507  }
    22992508  return mrb_str_to_inum(mrb, self, base, FALSE);
    23002509}
    23012510
    2302 MRB_API double
    2303 mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck)
    2304 {
     2511#ifndef MRB_WITHOUT_FLOAT
     2512double
     2513mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck)
     2514{
     2515  char buf[DBL_DIG * 4 + 20];
     2516  const char *p = s, *p2;
     2517  const char *pend = p + len;
    23052518  char *end;
    2306   char buf[DBL_DIG * 4 + 10];
     2519  char *n;
     2520  char prev = 0;
    23072521  double d;
    2308 
    2309   enum {max_width = 20};
     2522  mrb_bool dot = FALSE;
    23102523
    23112524  if (!p) return 0.0;
    2312   while (ISSPACE(*p)) p++;
    2313 
    2314   if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
    2315     return 0.0;
    2316   }
     2525  while (p<pend && ISSPACE(*p)) p++;
     2526  p2 = p;
     2527
     2528  if (pend - p > 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
     2529    mrb_value x;
     2530
     2531    if (!badcheck) return 0.0;
     2532    x = mrb_str_len_to_inum(mrb, p, pend-p, 0, badcheck);
     2533    if (mrb_fixnum_p(x))
     2534      d = (double)mrb_fixnum(x);
     2535    else /* if (mrb_float_p(x)) */
     2536      d = mrb_float(x);
     2537    return d;
     2538  }
     2539  while (p < pend) {
     2540    if (!*p) {
     2541      if (badcheck) {
     2542        mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte");
     2543        /* not reached */
     2544      }
     2545      pend = p;
     2546      p = p2;
     2547      goto nocopy;
     2548    }
     2549    if (!badcheck && *p == ' ') {
     2550      pend = p;
     2551      p = p2;
     2552      goto nocopy;
     2553    }
     2554    if (*p == '_') break;
     2555    p++;
     2556  }
     2557  p = p2;
     2558  n = buf;
     2559  while (p < pend) {
     2560    char c = *p++;
     2561    if (c == '.') dot = TRUE;
     2562    if (c == '_') {
     2563      /* remove an underscore between digits */
     2564      if (n == buf || !ISDIGIT(prev) || p == pend) {
     2565        if (badcheck) goto bad;
     2566        break;
     2567      }
     2568    }
     2569    else if (badcheck && prev == '_' && !ISDIGIT(c)) goto bad;
     2570    else {
     2571      const char *bend = buf+sizeof(buf)-1;
     2572      if (n==bend) {            /* buffer overflow */
     2573        if (dot) break;         /* cut off remaining fractions */
     2574        return INFINITY;
     2575      }
     2576      *n++ = c;
     2577    }
     2578    prev = c;
     2579  }
     2580  *n = '\0';
     2581  p = buf;
     2582  pend = n;
     2583nocopy:
    23172584  d = mrb_float_read(p, &end);
    23182585  if (p == end) {
    23192586    if (badcheck) {
    23202587bad:
    2321       mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%S)", mrb_str_new_cstr(mrb, p));
     2588      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%!s)", s);
    23222589      /* not reached */
    23232590    }
    23242591    return d;
    23252592  }
    2326   if (*end) {
    2327     char *n = buf;
    2328     char *e = buf + sizeof(buf) - 1;
    2329     char prev = 0;
    2330 
    2331     while (p < end && n < e) prev = *n++ = *p++;
    2332     while (*p) {
    2333       if (*p == '_') {
    2334         /* remove underscores between digits */
    2335         if (badcheck) {
    2336           if (n == buf || !ISDIGIT(prev)) goto bad;
    2337           ++p;
    2338           if (!ISDIGIT(*p)) goto bad;
    2339         }
    2340         else {
    2341           while (*++p == '_');
    2342           continue;
    2343         }
    2344       }
    2345       prev = *p++;
    2346       if (n < e) *n++ = prev;
    2347     }
    2348     *n = '\0';
    2349     p = buf;
    2350 
    2351     if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
    2352       return 0.0;
    2353     }
    2354 
    2355     d = mrb_float_read(p, &end);
    2356     if (badcheck) {
    2357       if (!end || p == end) goto bad;
    2358       while (*end && ISSPACE(*end)) end++;
    2359       if (*end) goto bad;
    2360     }
     2593  if (badcheck) {
     2594    if (!end || p == end) goto bad;
     2595    while (end<pend && ISSPACE(*end)) end++;
     2596    if (end<pend) goto bad;
    23612597  }
    23622598  return d;
     2599}
     2600
     2601MRB_API double
     2602mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck)
     2603{
     2604  return mrb_str_len_to_dbl(mrb, s, strlen(s), badcheck);
    23632605}
    23642606
     
    23662608mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck)
    23672609{
    2368   char *s;
    2369   mrb_int len;
    2370 
    2371   str = mrb_str_to_str(mrb, str);
    2372   s = RSTRING_PTR(str);
    2373   len = RSTRING_LEN(str);
    2374   if (s) {
    2375     if (badcheck && memchr(s, '\0', len)) {
    2376       mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte");
    2377     }
    2378     if (s[len]) {    /* no sentinel somehow */
    2379       struct RString *temp_str = str_new(mrb, s, len);
    2380       s = RSTR_PTR(temp_str);
    2381     }
    2382   }
    2383   return mrb_cstr_to_dbl(mrb, s, badcheck);
     2610  return mrb_str_len_to_dbl(mrb, RSTRING_PTR(str), RSTRING_LEN(str), badcheck);
    23842611}
    23852612
     
    24032630  return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE));
    24042631}
     2632#endif
    24052633
    24062634/* 15.2.10.5.40 */
     
    24082636 *  call-seq:
    24092637 *     str.to_s     => str
    2410  *     str.to_str   => str
    24112638 *
    24122639 *  Returns the receiver.
     
    24362663  mrb_bool modify = FALSE;
    24372664
    2438   mrb_str_modify(mrb, s);
     2665  mrb_str_modify_keep_ascii(mrb, s);
    24392666  p = RSTRING_PTR(str);
    24402667  pend = RSTRING_END(str);
     
    24722699}
    24732700
    2474 #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
    2475 
    24762701/*
    24772702 *  call-seq:
     
    24842709mrb_str_dump(mrb_state *mrb, mrb_value str)
    24852710{
    2486   mrb_int len;
    2487   const char *p, *pend;
    2488   char *q;
    2489   struct RString *result;
    2490 
    2491   len = 2;                  /* "" */
    2492   p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
    2493   while (p < pend) {
    2494     unsigned char c = *p++;
    2495     switch (c) {
    2496       case '"':  case '\\':
    2497       case '\n': case '\r':
    2498       case '\t': case '\f':
    2499       case '\013': case '\010': case '\007': case '\033':
    2500         len += 2;
    2501         break;
    2502 
    2503       case '#':
    2504         len += IS_EVSTR(p, pend) ? 2 : 1;
    2505         break;
    2506 
    2507       default:
    2508         if (ISPRINT(c)) {
    2509           len++;
    2510         }
    2511         else {
    2512           len += 4;                /* \NNN */
    2513         }
    2514         break;
    2515     }
    2516   }
    2517 
    2518   result = str_new(mrb, 0, len);
    2519   str_with_class(mrb, result, str);
    2520   p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
    2521   q = RSTR_PTR(result);
    2522   *q++ = '"';
    2523   while (p < pend) {
    2524     unsigned char c = *p++;
    2525 
    2526     switch (c) {
    2527       case '"':
    2528       case '\\':
    2529         *q++ = '\\';
    2530         *q++ = c;
    2531         break;
    2532 
    2533       case '\n':
    2534         *q++ = '\\';
    2535         *q++ = 'n';
    2536         break;
    2537 
    2538       case '\r':
    2539         *q++ = '\\';
    2540         *q++ = 'r';
    2541         break;
    2542 
    2543       case '\t':
    2544         *q++ = '\\';
    2545         *q++ = 't';
    2546         break;
    2547 
    2548       case '\f':
    2549         *q++ = '\\';
    2550         *q++ = 'f';
    2551         break;
    2552 
    2553       case '\013':
    2554         *q++ = '\\';
    2555         *q++ = 'v';
    2556         break;
    2557 
    2558       case '\010':
    2559         *q++ = '\\';
    2560         *q++ = 'b';
    2561         break;
    2562 
    2563       case '\007':
    2564         *q++ = '\\';
    2565         *q++ = 'a';
    2566         break;
    2567 
    2568       case '\033':
    2569         *q++ = '\\';
    2570         *q++ = 'e';
    2571         break;
    2572 
    2573       case '#':
    2574         if (IS_EVSTR(p, pend)) *q++ = '\\';
    2575         *q++ = '#';
    2576         break;
    2577 
    2578       default:
    2579         if (ISPRINT(c)) {
    2580           *q++ = c;
    2581         }
    2582         else {
    2583           *q++ = '\\';
    2584           q[2] = '0' + c % 8; c /= 8;
    2585           q[1] = '0' + c % 8; c /= 8;
    2586           q[0] = '0' + c % 8;
    2587           q += 3;
    2588         }
    2589     }
    2590   }
    2591   *q = '"';
    2592   return mrb_obj_value(result);
     2711  return str_escape(mrb, str, FALSE);
    25932712}
    25942713
     
    25962715mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
    25972716{
    2598   str_buf_cat(mrb, mrb_str_ptr(str), ptr, len);
     2717  struct RString *s = mrb_str_ptr(str);
     2718  size_t capa;
     2719  size_t total;
     2720  ptrdiff_t off = -1;
     2721
     2722  if (len == 0) return str;
     2723  mrb_str_modify(mrb, s);
     2724  if (ptr >= RSTR_PTR(s) && ptr <= RSTR_PTR(s) + (size_t)RSTR_LEN(s)) {
     2725      off = ptr - RSTR_PTR(s);
     2726  }
     2727
     2728  capa = RSTR_CAPA(s);
     2729  total = RSTR_LEN(s)+len;
     2730  if (total >= MRB_SSIZE_MAX) {
     2731  size_error:
     2732    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
     2733  }
     2734  if (capa <= total) {
     2735    if (capa == 0) capa = 1;
     2736    while (capa <= total) {
     2737      if (capa <= MRB_SSIZE_MAX / 2) {
     2738        capa *= 2;
     2739      }
     2740      else {
     2741        capa = total+1;
     2742      }
     2743    }
     2744    if (capa <= total || capa > MRB_SSIZE_MAX) {
     2745      goto size_error;
     2746    }
     2747    resize_capa(mrb, s, capa);
     2748  }
     2749  if (off != -1) {
     2750      ptr = RSTR_PTR(s) + off;
     2751  }
     2752  memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len);
     2753  mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX);
     2754  RSTR_SET_LEN(s, total);
     2755  RSTR_PTR(s)[total] = '\0';   /* sentinel */
    25992756  return str;
    26002757}
     
    26092766mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2)
    26102767{
     2768  if (mrb_str_ptr(str) == mrb_str_ptr(str2)) {
     2769    mrb_str_modify(mrb, mrb_str_ptr(str));
     2770  }
    26112771  return mrb_str_cat(mrb, str, RSTRING_PTR(str2), RSTRING_LEN(str2));
    26122772}
     
    26152775mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2)
    26162776{
    2617   str2 = mrb_str_to_str(mrb, str2);
     2777  mrb_to_str(mrb, str2);
    26182778  return mrb_str_cat_str(mrb, str1, str2);
    26192779}
    2620 
    2621 #define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */
    26222780
    26232781/*
     
    26352793mrb_str_inspect(mrb_state *mrb, mrb_value str)
    26362794{
    2637   const char *p, *pend;
    2638   char buf[CHAR_ESC_LEN + 1];
    2639   mrb_value result = mrb_str_new_lit(mrb, "\"");
    2640 
    2641   p = RSTRING_PTR(str); pend = RSTRING_END(str);
    2642   for (;p < pend; p++) {
    2643     unsigned char c, cc;
    2644 #ifdef MRB_UTF8_STRING
    2645     mrb_int clen;
    2646 
    2647     clen = utf8len(p, pend);
    2648     if (clen > 1) {
    2649       mrb_int i;
    2650 
    2651       for (i=0; i<clen; i++) {
    2652         buf[i] = p[i];
    2653       }
    2654       mrb_str_cat(mrb, result, buf, clen);
    2655       p += clen-1;
    2656       continue;
    2657     }
    2658 #endif
    2659     c = *p;
    2660     if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
    2661       buf[0] = '\\'; buf[1] = c;
    2662       mrb_str_cat(mrb, result, buf, 2);
    2663       continue;
    2664     }
    2665     if (ISPRINT(c)) {
    2666       buf[0] = c;
    2667       mrb_str_cat(mrb, result, buf, 1);
    2668       continue;
    2669     }
    2670     switch (c) {
    2671       case '\n': cc = 'n'; break;
    2672       case '\r': cc = 'r'; break;
    2673       case '\t': cc = 't'; break;
    2674       case '\f': cc = 'f'; break;
    2675       case '\013': cc = 'v'; break;
    2676       case '\010': cc = 'b'; break;
    2677       case '\007': cc = 'a'; break;
    2678       case 033: cc = 'e'; break;
    2679       default: cc = 0; break;
    2680     }
    2681     if (cc) {
    2682       buf[0] = '\\';
    2683       buf[1] = (char)cc;
    2684       mrb_str_cat(mrb, result, buf, 2);
    2685       continue;
    2686     }
    2687     else {
    2688       buf[0] = '\\';
    2689       buf[3] = '0' + c % 8; c /= 8;
    2690       buf[2] = '0' + c % 8; c /= 8;
    2691       buf[1] = '0' + c % 8;
    2692       mrb_str_cat(mrb, result, buf, 4);
    2693       continue;
    2694     }
    2695   }
    2696   mrb_str_cat_lit(mrb, result, "\"");
    2697 
    2698   return result;
     2795  return str_escape(mrb, str, TRUE);
    26992796}
    27002797
     
    27222819}
    27232820
     2821/*
     2822 *  call-seq:
     2823 *     str.getbyte(index)          -> 0 .. 255
     2824 *
     2825 *  returns the <i>index</i>th byte as an integer.
     2826 */
     2827static mrb_value
     2828mrb_str_getbyte(mrb_state *mrb, mrb_value str)
     2829{
     2830  mrb_int pos;
     2831  mrb_get_args(mrb, "i", &pos);
     2832
     2833  if (pos < 0)
     2834    pos += RSTRING_LEN(str);
     2835  if (pos < 0 ||  RSTRING_LEN(str) <= pos)
     2836    return mrb_nil_value();
     2837
     2838  return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
     2839}
     2840
     2841/*
     2842 *  call-seq:
     2843 *     str.setbyte(index, integer) -> integer
     2844 *
     2845 *  modifies the <i>index</i>th byte as <i>integer</i>.
     2846 */
     2847static mrb_value
     2848mrb_str_setbyte(mrb_state *mrb, mrb_value str)
     2849{
     2850  mrb_int pos, byte;
     2851  mrb_int len;
     2852
     2853  mrb_get_args(mrb, "ii", &pos, &byte);
     2854
     2855  len = RSTRING_LEN(str);
     2856  if (pos < -len || len <= pos)
     2857    mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos);
     2858  if (pos < 0)
     2859    pos += len;
     2860
     2861  mrb_str_modify(mrb, mrb_str_ptr(str));
     2862  byte &= 0xff;
     2863  RSTRING_PTR(str)[pos] = (unsigned char)byte;
     2864  return mrb_fixnum_value((unsigned char)byte);
     2865}
     2866
     2867/*
     2868 *  call-seq:
     2869 *     str.byteslice(integer)           -> new_str or nil
     2870 *     str.byteslice(integer, integer)   -> new_str or nil
     2871 *     str.byteslice(range)            -> new_str or nil
     2872 *
     2873 *  Byte Reference---If passed a single Integer, returns a
     2874 *  substring of one byte at that position. If passed two Integer
     2875 *  objects, returns a substring starting at the offset given by the first, and
     2876 *  a length given by the second. If given a Range, a substring containing
     2877 *  bytes at offsets given by the range is returned. In all three cases, if
     2878 *  an offset is negative, it is counted from the end of <i>str</i>. Returns
     2879 *  <code>nil</code> if the initial offset falls outside the string, the length
     2880 *  is negative, or the beginning of the range is greater than the end.
     2881 *  The encoding of the resulted string keeps original encoding.
     2882 *
     2883 *     "hello".byteslice(1)     #=> "e"
     2884 *     "hello".byteslice(-1)    #=> "o"
     2885 *     "hello".byteslice(1, 2)  #=> "el"
     2886 *     "\x80\u3042".byteslice(1, 3) #=> "\u3042"
     2887 *     "\x03\u3042\xff".byteslice(1..3) #=> "\u3042"
     2888 */
     2889static mrb_value
     2890mrb_str_byteslice(mrb_state *mrb, mrb_value str)
     2891{
     2892  mrb_value a1, a2;
     2893  mrb_int str_len = RSTRING_LEN(str), beg, len;
     2894  mrb_bool empty = TRUE;
     2895
     2896  if (mrb_get_args(mrb, "o|o", &a1, &a2) == 2) {
     2897    beg = mrb_fixnum(mrb_to_int(mrb, a1));
     2898    len = mrb_fixnum(mrb_to_int(mrb, a2));
     2899  }
     2900  else if (mrb_range_p(a1)) {
     2901    if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) {
     2902      return mrb_nil_value();
     2903    }
     2904  }
     2905  else {
     2906    beg = mrb_fixnum(mrb_to_int(mrb, a1));
     2907    len = 1;
     2908    empty = FALSE;
     2909  }
     2910
     2911  if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) {
     2912    return mrb_str_byte_subseq(mrb, str, beg, len);
     2913  }
     2914  else {
     2915    return mrb_nil_value();
     2916  }
     2917}
     2918
    27242919/* ---------------------------*/
    27252920void
     
    27282923  struct RClass *s;
    27292924
    2730   mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string");
     2925  mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << MRB_STR_EMBED_LEN_BIT),
     2926                    "pointer size too big for embedded string");
    27312927
    27322928  mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class);             /* 15.2.10 */
     
    27402936  mrb_define_method(mrb, s, "*",               mrb_str_times,           MRB_ARGS_REQ(1)); /* 15.2.10.5.5  */
    27412937  mrb_define_method(mrb, s, "[]",              mrb_str_aref_m,          MRB_ARGS_ANY());  /* 15.2.10.5.6  */
     2938  mrb_define_method(mrb, s, "[]=",             mrb_str_aset_m,          MRB_ARGS_ANY());
    27422939  mrb_define_method(mrb, s, "capitalize",      mrb_str_capitalize,      MRB_ARGS_NONE()); /* 15.2.10.5.7  */
    27432940  mrb_define_method(mrb, s, "capitalize!",     mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8  */
     
    27532950  mrb_define_method(mrb, s, "hash",            mrb_str_hash_m,          MRB_ARGS_NONE()); /* 15.2.10.5.20 */
    27542951  mrb_define_method(mrb, s, "include?",        mrb_str_include,         MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */
    2755   mrb_define_method(mrb, s, "index",           mrb_str_index,           MRB_ARGS_ANY());  /* 15.2.10.5.22 */
     2952  mrb_define_method(mrb, s, "index",           mrb_str_index_m,         MRB_ARGS_ARG(1,1));  /* 15.2.10.5.22 */
    27562953  mrb_define_method(mrb, s, "initialize",      mrb_str_init,            MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */
    27572954  mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace,         MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */
     
    27662963  mrb_define_method(mrb, s, "split",           mrb_str_split_m,         MRB_ARGS_ANY());  /* 15.2.10.5.35 */
    27672964
     2965#ifndef MRB_WITHOUT_FLOAT
    27682966  mrb_define_method(mrb, s, "to_f",            mrb_str_to_f,            MRB_ARGS_NONE()); /* 15.2.10.5.38 */
     2967#endif
    27692968  mrb_define_method(mrb, s, "to_i",            mrb_str_to_i,            MRB_ARGS_ANY());  /* 15.2.10.5.39 */
    27702969  mrb_define_method(mrb, s, "to_s",            mrb_str_to_s,            MRB_ARGS_NONE()); /* 15.2.10.5.40 */
     
    27752974  mrb_define_method(mrb, s, "inspect",         mrb_str_inspect,         MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */
    27762975  mrb_define_method(mrb, s, "bytes",           mrb_str_bytes,           MRB_ARGS_NONE());
    2777 }
    2778 
    2779 /*
    2780  *      Source code for the "strtod" library procedure.
     2976
     2977  mrb_define_method(mrb, s, "getbyte",         mrb_str_getbyte,         MRB_ARGS_REQ(1));
     2978  mrb_define_method(mrb, s, "setbyte",         mrb_str_setbyte,         MRB_ARGS_REQ(2));
     2979  mrb_define_method(mrb, s, "byteslice",       mrb_str_byteslice,       MRB_ARGS_ARG(1,1));
     2980}
     2981
     2982#ifndef MRB_WITHOUT_FLOAT
     2983/*
     2984 * Source code for the "strtod" library procedure.
    27812985 *
    27822986 * Copyright (c) 1988-1993 The Regents of the University of California.
     
    28043008static const double powersOf10[] = {/* Table giving binary powers of 10.  Entry */
    28053009    10.,                            /* is 10^2^i.  Used to convert decimal */
    2806     100.,                           /* exponents into floating-point numbers. */
     3010    100.,                           /* exponents into floating-point numbers. */
    28073011    1.0e4,
    28083012    1.0e8,
     
    28163020MRB_API double
    28173021mrb_float_read(const char *string, char **endPtr)
    2818 /*  const char *string;            A decimal ASCII floating-point number,
    2819                                 * optionally preceded by white space.
    2820                                 * Must have form "-I.FE-X", where I is the
    2821                                 * integer part of the mantissa, F is the
    2822                                 * fractional part of the mantissa, and X
    2823                                 * is the exponent.  Either of the signs
    2824                                 * may be "+", "-", or omitted.  Either I
    2825                                 * or F may be omitted, or both.  The decimal
    2826                                 * point isn't necessary unless F is present.
    2827                                 * The "E" may actually be an "e".  E and X
    2828                                 * may both be omitted (but not just one).
    2829                                 */
    2830 /*  char **endPtr;                 If non-NULL, store terminating character's
    2831                                 * address here. */
     3022/*  const char *string;            A decimal ASCII floating-point number,
     3023                                * optionally preceded by white space.
     3024                                * Must have form "-I.FE-X", where I is the
     3025                                * integer part of the mantissa, F is the
     3026                                * fractional part of the mantissa, and X
     3027                                * is the exponent.  Either of the signs
     3028                                * may be "+", "-", or omitted.  Either I
     3029                                * or F may be omitted, or both.  The decimal
     3030                                * point isn't necessary unless F is present.
     3031                                * The "E" may actually be an "e".  E and X
     3032                                * may both be omitted (but not just one).
     3033                                */
     3034/*  char **endPtr;                 If non-NULL, store terminating character's
     3035                                * address here. */
    28323036{
    28333037    int sign, expSign = FALSE;
    28343038    double fraction, dblExp;
    28353039    const double *d;
    2836     register const char *p;
    2837     register int c;
    2838     int exp = 0;                /* Exponent read from "EX" field. */
    2839     int fracExp = 0;            /* Exponent that derives from the fractional
    2840                                 * part.  Under normal circumstatnces, it is
    2841                                 * the negative of the number of digits in F.
    2842                                 * However, if I is very long, the last digits
    2843                                 * of I get dropped (otherwise a long I with a
    2844                                 * large negative exponent could cause an
    2845                                 * unnecessary overflow on I alone).  In this
    2846                                 * case, fracExp is incremented one for each
    2847                                 * dropped digit. */
    2848     int mantSize;               /* Number of digits in mantissa. */
    2849     int decPt;                  /* Number of mantissa digits BEFORE decimal
    2850                                 * point. */
    2851     const char *pExp;           /* Temporarily holds location of exponent
    2852                                 * in string. */
     3040    const char *p;
     3041    int c;
     3042    int exp = 0;                /* Exponent read from "EX" field. */
     3043    int fracExp = 0;            /* Exponent that derives from the fractional
     3044                                * part.  Under normal circumstatnces, it is
     3045                                * the negative of the number of digits in F.
     3046                                * However, if I is very long, the last digits
     3047                                * of I get dropped (otherwise a long I with a
     3048                                * large negative exponent could cause an
     3049                                * unnecessary overflow on I alone).  In this
     3050                                * case, fracExp is incremented one for each
     3051                                * dropped digit. */
     3052    int mantSize;               /* Number of digits in mantissa. */
     3053    int decPt;                  /* Number of mantissa digits BEFORE decimal
     3054                                * point. */
     3055    const char *pExp;           /* Temporarily holds location of exponent
     3056                                * in string. */
    28533057
    28543058    /*
     
    28573061
    28583062    p = string;
    2859     while (isspace(*p)) {
    2860         p += 1;
     3063    while (ISSPACE(*p)) {
     3064      p += 1;
    28613065    }
    28623066    if (*p == '-') {
    2863         sign = TRUE;
    2864         p += 1;
     3067      sign = TRUE;
     3068      p += 1;
    28653069    }
    28663070    else {
    2867         if (*p == '+') {
    2868             p += 1;
    2869         }
    2870         sign = FALSE;
     3071      if (*p == '+') {
     3072        p += 1;
     3073      }
     3074      sign = FALSE;
    28713075    }
    28723076
     
    28793083    for (mantSize = 0; ; mantSize += 1)
    28803084    {
    2881         c = *p;
    2882         if (!isdigit(c)) {
    2883             if ((c != '.') || (decPt >= 0)) {
    2884                 break;
    2885             }
    2886             decPt = mantSize;
    2887         }
    2888         p += 1;
     3085      c = *p;
     3086      if (!ISDIGIT(c)) {
     3087        if ((c != '.') || (decPt >= 0)) {
     3088          break;
     3089        }
     3090        decPt = mantSize;
     3091      }
     3092      p += 1;
    28893093    }
    28903094
     
    28993103    p -= mantSize;
    29003104    if (decPt < 0) {
    2901         decPt = mantSize;
     3105      decPt = mantSize;
    29023106    }
    29033107    else {
    2904         mantSize -= 1;                  /* One of the digits was the point. */
     3108      mantSize -= 1; /* One of the digits was the point. */
    29053109    }
    29063110    if (mantSize > 18) {
    2907         if (decPt - 18 > 29999) {
    2908             fracExp = 29999;
    2909         }
    2910         else {
    2911             fracExp = decPt - 18;
    2912         }
    2913         mantSize = 18;
     3111      if (decPt - 18 > 29999) {
     3112        fracExp = 29999;
     3113      }
     3114      else {
     3115        fracExp = decPt - 18;
     3116      }
     3117      mantSize = 18;
    29143118    }
    29153119    else {
    2916         fracExp = decPt - mantSize;
     3120      fracExp = decPt - mantSize;
    29173121    }
    29183122    if (mantSize == 0) {
    2919         fraction = 0.0;
    2920         p = string;
    2921         goto done;
     3123      fraction = 0.0;
     3124      p = string;
     3125      goto done;
    29223126    }
    29233127    else {
    2924         int frac1, frac2;
    2925         frac1 = 0;
    2926         for ( ; mantSize > 9; mantSize -= 1)
    2927         {
    2928             c = *p;
    2929             p += 1;
    2930             if (c == '.') {
    2931                 c = *p;
    2932                 p += 1;
    2933             }
    2934             frac1 = 10*frac1 + (c - '0');
    2935         }
    2936         frac2 = 0;
    2937         for (; mantSize > 0; mantSize -= 1)
    2938         {
    2939             c = *p;
    2940             p += 1;
    2941             if (c == '.') {
    2942                 c = *p;
    2943                 p += 1;
    2944             }
    2945             frac2 = 10*frac2 + (c - '0');
    2946         }
    2947         fraction = (1.0e9 * frac1) + frac2;
     3128      int frac1, frac2;
     3129      frac1 = 0;
     3130      for ( ; mantSize > 9; mantSize -= 1)
     3131      {
     3132        c = *p;
     3133        p += 1;
     3134        if (c == '.') {
     3135          c = *p;
     3136          p += 1;
     3137        }
     3138        frac1 = 10*frac1 + (c - '0');
     3139      }
     3140      frac2 = 0;
     3141      for (; mantSize > 0; mantSize -= 1)
     3142      {
     3143        c = *p;
     3144        p += 1;
     3145        if (c == '.') {
     3146          c = *p;
     3147          p += 1;
     3148        }
     3149        frac2 = 10*frac2 + (c - '0');
     3150      }
     3151      fraction = (1.0e9 * frac1) + frac2;
    29483152    }
    29493153
     
    29543158    p = pExp;
    29553159    if ((*p == 'E') || (*p == 'e')) {
    2956         p += 1;
    2957         if (*p == '-') {
    2958             expSign = TRUE;
    2959             p += 1;
    2960         }
    2961         else {
    2962             if (*p == '+') {
    2963                 p += 1;
    2964             }
    2965             expSign = FALSE;
    2966         }
    2967         while (isdigit(*p)) {
    2968             exp = exp * 10 + (*p - '0');
    2969             if (exp > 19999) {
    2970                 exp = 19999;
    2971             }
    2972             p += 1;
    2973         }
     3160      p += 1;
     3161      if (*p == '-') {
     3162        expSign = TRUE;
     3163        p += 1;
     3164      }
     3165      else {
     3166        if (*p == '+') {
     3167          p += 1;
     3168        }
     3169        expSign = FALSE;
     3170      }
     3171      while (ISDIGIT(*p)) {
     3172        exp = exp * 10 + (*p - '0');
     3173        if (exp > 19999) {
     3174          exp = 19999;
     3175        }
     3176        p += 1;
     3177      }
    29743178    }
    29753179    if (expSign) {
    2976         exp = fracExp - exp;
     3180      exp = fracExp - exp;
    29773181    }
    29783182    else {
    2979         exp = fracExp + exp;
     3183      exp = fracExp + exp;
    29803184    }
    29813185
     
    29883192
    29893193    if (exp < 0) {
    2990         expSign = TRUE;
    2991         exp = -exp;
     3194      expSign = TRUE;
     3195      exp = -exp;
    29923196    }
    29933197    else {
    2994         expSign = FALSE;
     3198      expSign = FALSE;
    29953199    }
    29963200    if (exp > maxExponent) {
    2997         exp = maxExponent;
    2998         errno = ERANGE;
     3201      exp = maxExponent;
     3202      errno = ERANGE;
    29993203    }
    30003204    dblExp = 1.0;
    30013205    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
    3002         if (exp & 01) {
    3003             dblExp *= *d;
    3004         }
     3206      if (exp & 01) {
     3207        dblExp *= *d;
     3208      }
    30053209    }
    30063210    if (expSign) {
    3007         fraction /= dblExp;
     3211      fraction /= dblExp;
    30083212    }
    30093213    else {
    3010         fraction *= dblExp;
     3214      fraction *= dblExp;
    30113215    }
    30123216
    30133217done:
    30143218    if (endPtr != NULL) {
    3015         *endPtr = (char *) p;
     3219      *endPtr = (char *) p;
    30163220    }
    30173221
    30183222    if (sign) {
    3019         return -fraction;
     3223      return -fraction;
    30203224    }
    30213225    return fraction;
    30223226}
     3227#endif
  • EcnlProtoTool/trunk/mruby-2.1.1/src/symbol.c

    r331 r439  
    1616typedef struct symbol_name {
    1717  mrb_bool lit : 1;
     18  uint8_t prev;
    1819  uint16_t len;
    1920  const char *name;
    2021} symbol_name;
    2122
    22 static inline khint_t
    23 sym_hash_func(mrb_state *mrb, mrb_sym s)
    24 {
    25   khint_t h = 0;
    26   size_t i, len = mrb->symtbl[s].len;
    27   const char *p = mrb->symtbl[s].name;
    28 
    29   for (i=0; i<len; i++) {
    30     h = (h << 5) - h + *p++;
    31   }
    32   return h;
    33 }
    34 #define sym_hash_equal(mrb,a, b) (mrb->symtbl[a].len == mrb->symtbl[b].len && memcmp(mrb->symtbl[a].name, mrb->symtbl[b].name, mrb->symtbl[a].len) == 0)
    35 
    36 KHASH_DECLARE(n2s, mrb_sym, mrb_sym, FALSE)
    37 KHASH_DEFINE (n2s, mrb_sym, mrb_sym, FALSE, sym_hash_func, sym_hash_equal)
    38 /* ------------------------------------------------------ */
     23#define SYMBOL_INLINE_BIT_POS       1
     24#define SYMBOL_INLINE_LOWER_BIT_POS 2
     25#define SYMBOL_INLINE               (1 << (SYMBOL_INLINE_BIT_POS - 1))
     26#define SYMBOL_INLINE_LOWER         (1 << (SYMBOL_INLINE_LOWER_BIT_POS - 1))
     27#define SYMBOL_NORMAL_SHIFT         SYMBOL_INLINE_BIT_POS
     28#define SYMBOL_INLINE_SHIFT         SYMBOL_INLINE_LOWER_BIT_POS
     29#ifdef MRB_ENABLE_ALL_SYMBOLS
     30# define SYMBOL_INLINE_P(sym) FALSE
     31# define SYMBOL_INLINE_LOWER_P(sym) FALSE
     32# define sym_inline_pack(name, len) 0
     33# define sym_inline_unpack(sym, buf, lenp) NULL
     34#else
     35# define SYMBOL_INLINE_P(sym) ((sym) & SYMBOL_INLINE)
     36# define SYMBOL_INLINE_LOWER_P(sym) ((sym) & SYMBOL_INLINE_LOWER)
     37#endif
    3938
    4039static void
     
    4645}
    4746
     47#ifndef MRB_ENABLE_ALL_SYMBOLS
     48static const char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
     49
     50static mrb_sym
     51sym_inline_pack(const char *name, size_t len)
     52{
     53  const size_t lower_length_max = (MRB_SYMBOL_BIT - 2) / 5;
     54  const size_t mix_length_max   = (MRB_SYMBOL_BIT - 2) / 6;
     55
     56  char c;
     57  const char *p;
     58  size_t i;
     59  mrb_sym sym = 0;
     60  mrb_bool lower = TRUE;
     61
     62  if (len > lower_length_max) return 0; /* too long */
     63  for (i=0; i<len; i++) {
     64    uint32_t bits;
     65
     66    c = name[i];
     67    if (c == 0) return 0;       /* NUL in name */
     68    p = strchr(pack_table, (int)c);
     69    if (p == 0) return 0;       /* non alnum char */
     70    bits = (uint32_t)(p - pack_table)+1;
     71    if (bits > 27) lower = FALSE;
     72    if (i >= mix_length_max) break;
     73    sym |= bits<<(i*6+SYMBOL_INLINE_SHIFT);
     74  }
     75  if (lower) {
     76    sym = 0;
     77    for (i=0; i<len; i++) {
     78      uint32_t bits;
     79
     80      c = name[i];
     81      p = strchr(pack_table, (int)c);
     82      bits = (uint32_t)(p - pack_table)+1;
     83      sym |= bits<<(i*5+SYMBOL_INLINE_SHIFT);
     84    }
     85    return sym | SYMBOL_INLINE | SYMBOL_INLINE_LOWER;
     86  }
     87  if (len > mix_length_max) return 0;
     88  return sym | SYMBOL_INLINE;
     89}
     90
     91static const char*
     92sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp)
     93{
     94  int bit_per_char = SYMBOL_INLINE_LOWER_P(sym) ? 5 : 6;
     95  int i;
     96
     97  mrb_assert(SYMBOL_INLINE_P(sym));
     98
     99  for (i=0; i<30/bit_per_char; i++) {
     100    uint32_t bits = sym>>(i*bit_per_char+SYMBOL_INLINE_SHIFT) & ((1<<bit_per_char)-1);
     101    if (bits == 0) break;
     102    buf[i] = pack_table[bits-1];;
     103  }
     104  buf[i] = '\0';
     105  if (lenp) *lenp = i;
     106  return buf;
     107}
     108#endif
     109
     110static uint8_t
     111symhash(const char *key, size_t len)
     112{
     113    uint32_t hash, i;
     114
     115    for(hash = i = 0; i < len; ++i) {
     116        hash += key[i];
     117        hash += (hash << 10);
     118        hash ^= (hash >> 6);
     119    }
     120    hash += (hash << 3);
     121    hash ^= (hash >> 11);
     122    hash += (hash << 15);
     123    return hash & 0xff;
     124}
     125
     126static mrb_sym
     127find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp)
     128{
     129  mrb_sym i;
     130  symbol_name *sname;
     131  uint8_t hash;
     132
     133  /* inline symbol */
     134  i = sym_inline_pack(name, len);
     135  if (i > 0) return i;
     136
     137  hash = symhash(name, len);
     138  if (hashp) *hashp = hash;
     139
     140  i = mrb->symhash[hash];
     141  if (i == 0) return 0;
     142  do {
     143    sname = &mrb->symtbl[i];
     144    if (sname->len == len && memcmp(sname->name, name, len) == 0) {
     145      return i<<SYMBOL_NORMAL_SHIFT;
     146    }
     147    if (sname->prev == 0xff) {
     148      i -= 0xff;
     149      sname = &mrb->symtbl[i];
     150      while (mrb->symtbl < sname) {
     151        if (sname->len == len && memcmp(sname->name, name, len) == 0) {
     152          return (mrb_sym)(sname - mrb->symtbl)<<SYMBOL_NORMAL_SHIFT;
     153        }
     154        sname--;
     155      }
     156      return 0;
     157    }
     158    i -= sname->prev;
     159  } while (sname->prev > 0);
     160  return 0;
     161}
     162
    48163static mrb_sym
    49164sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
    50165{
    51   khash_t(n2s) *h = mrb->name2sym;
    52   symbol_name *sname = mrb->symtbl; /* symtbl[0] for working memory */
    53   khiter_t k;
    54166  mrb_sym sym;
    55   char *p;
     167  symbol_name *sname;
     168  uint8_t hash;
    56169
    57170  sym_validate_len(mrb, len);
    58   if (sname) {
    59     sname->lit = lit;
    60     sname->len = (uint16_t)len;
    61     sname->name = name;
    62     k = kh_get(n2s, mrb, h, 0);
    63     if (k != kh_end(h))
    64       return kh_key(h, k);
    65   }
     171  sym = find_symbol(mrb, name, len, &hash);
     172  if (sym > 0) return sym;
    66173
    67174  /* registering a new symbol */
     
    69176  if (mrb->symcapa < sym) {
    70177    if (mrb->symcapa == 0) mrb->symcapa = 100;
    71     else mrb->symcapa = (size_t)(mrb->symcapa * 1.2);
     178    else mrb->symcapa = (size_t)(mrb->symcapa * 6 / 5);
    72179    mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1));
    73180  }
     
    79186  }
    80187  else {
    81     p = (char *)mrb_malloc(mrb, len+1);
     188    char *p = (char *)mrb_malloc(mrb, len+1);
    82189    memcpy(p, name, len);
    83190    p[len] = 0;
     
    85192    sname->lit = FALSE;
    86193  }
    87   kh_put(n2s, mrb, h, sym);
    88 
    89   return sym;
     194  if (mrb->symhash[hash]) {
     195    mrb_sym i = sym - mrb->symhash[hash];
     196    if (i > 0xff)
     197      sname->prev = 0xff;
     198    else
     199      sname->prev = i;
     200  }
     201  else {
     202    sname->prev = 0;
     203  }
     204  mrb->symhash[hash] = sym;
     205
     206  return sym<<SYMBOL_NORMAL_SHIFT;
    90207}
    91208
     
    117234mrb_check_intern(mrb_state *mrb, const char *name, size_t len)
    118235{
    119   khash_t(n2s) *h = mrb->name2sym;
    120   symbol_name *sname = mrb->symtbl;
    121   khiter_t k;
     236  mrb_sym sym;
    122237
    123238  sym_validate_len(mrb, len);
    124   sname->len = (uint16_t)len;
    125   sname->name = name;
    126 
    127   k = kh_get(n2s, mrb, h, 0);
    128   if (k != kh_end(h)) {
    129     return mrb_symbol_value(kh_key(h, k));
    130   }
     239  sym = find_symbol(mrb, name, len, NULL);
     240  if (sym > 0) return mrb_symbol_value(sym);
    131241  return mrb_nil_value();
    132242}
     
    135245mrb_check_intern_cstr(mrb_state *mrb, const char *name)
    136246{
    137   return mrb_check_intern(mrb, name, (mrb_int)strlen(name));
     247  return mrb_check_intern(mrb, name, strlen(name));
    138248}
    139249
     
    144254}
    145255
    146 /* lenp must be a pointer to a size_t variable */
    147 MRB_API const char*
    148 mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp)
    149 {
     256static const char*
     257sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp)
     258{
     259  if (SYMBOL_INLINE_P(sym)) return sym_inline_unpack(sym, buf, lenp);
     260
     261  sym >>= SYMBOL_NORMAL_SHIFT;
    150262  if (sym == 0 || mrb->symidx < sym) {
    151263    if (lenp) *lenp = 0;
     
    155267  if (lenp) *lenp = mrb->symtbl[sym].len;
    156268  return mrb->symtbl[sym].name;
     269}
     270
     271MRB_API const char*
     272mrb_sym_name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp)
     273{
     274  return sym2name_len(mrb, sym, mrb->symbuf, lenp);
    157275}
    158276
     
    168286  }
    169287  mrb_free(mrb, mrb->symtbl);
    170   kh_destroy(n2s, mrb, mrb->name2sym);
    171288}
    172289
     
    174291mrb_init_symtbl(mrb_state *mrb)
    175292{
    176   mrb->name2sym = kh_init(n2s, mrb);
    177293}
    178294
     
    210326 */
    211327
    212 
    213 /* 15.2.11.3.1  */
    214 /*
    215  *  call-seq:
    216  *     sym == obj   -> true or false
    217  *
    218  *  Equality---If <i>sym</i> and <i>obj</i> are exactly the same
    219  *  symbol, returns <code>true</code>.
    220  */
    221 
    222 static mrb_value
    223 sym_equal(mrb_state *mrb, mrb_value sym1)
    224 {
    225   mrb_value sym2;
    226 
    227   mrb_get_args(mrb, "o", &sym2);
    228 
    229   return mrb_bool_value(mrb_obj_equal(mrb, sym1, sym2));
    230 }
    231 
    232328/* 15.2.11.3.2  */
    233329/* 15.2.11.3.3  */
     
    242338 */
    243339static mrb_value
    244 mrb_sym_to_s(mrb_state *mrb, mrb_value sym)
    245 {
    246   mrb_sym id = mrb_symbol(sym);
    247   const char *p;
    248   mrb_int len;
    249 
    250   p = mrb_sym2name_len(mrb, id, &len);
    251   return mrb_str_new_static(mrb, p, len);
     340sym_to_s(mrb_state *mrb, mrb_value sym)
     341{
     342  return mrb_sym_str(mrb, mrb_symbol(sym));
    252343}
    253344
     
    388479          case '!': case '?': case '=': ++m;
    389480          default: break;
    390             }
    391481        }
     482      }
    392483      break;
    393484  }
     
    404495  char *sp;
    405496
    406   name = mrb_sym2name_len(mrb, id, &len);
     497  name = mrb_sym_name_len(mrb, id, &len);
    407498  str = mrb_str_new(mrb, 0, len+1);
    408499  sp = RSTRING_PTR(str);
    409   RSTRING_PTR(str)[0] = ':';
     500  sp[0] = ':';
    410501  memcpy(sp+1, name, len);
    411502  mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
    412503  if (!symname_p(name) || strlen(name) != (size_t)len) {
    413     str = mrb_str_dump(mrb, str);
     504    str = mrb_str_inspect(mrb, str);
    414505    sp = RSTRING_PTR(str);
    415506    sp[0] = ':';
    416507    sp[1] = '"';
    417508  }
     509#ifdef MRB_UTF8_STRING
     510  if (SYMBOL_INLINE_P(id)) RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
     511#endif
    418512  return str;
    419513}
    420514
    421515MRB_API mrb_value
    422 mrb_sym2str(mrb_state *mrb, mrb_sym sym)
     516mrb_sym_str(mrb_state *mrb, mrb_sym sym)
    423517{
    424518  mrb_int len;
    425   const char *name = mrb_sym2name_len(mrb, sym, &len);
     519  const char *name = mrb_sym_name_len(mrb, sym, &len);
    426520
    427521  if (!name) return mrb_undef_value(); /* can't happen */
     522  if (SYMBOL_INLINE_P(sym)) {
     523    mrb_value str = mrb_str_new(mrb, name, len);
     524    RSTR_SET_ASCII_FLAG(mrb_str_ptr(str));
     525    return str;
     526  }
    428527  return mrb_str_new_static(mrb, name, len);
    429528}
    430529
     530static const char*
     531sym_name(mrb_state *mrb, mrb_sym sym, mrb_bool dump)
     532{
     533  mrb_int len;
     534  const char *name = mrb_sym_name_len(mrb, sym, &len);
     535
     536  if (!name) return NULL;
     537  if (strlen(name) == (size_t)len && (!dump || symname_p(name))) {
     538    return name;
     539  }
     540  else {
     541    mrb_value str = SYMBOL_INLINE_P(sym) ?
     542      mrb_str_new(mrb, name, len) : mrb_str_new_static(mrb, name, len);
     543    str = mrb_str_dump(mrb, str);
     544    return RSTRING_PTR(str);
     545  }
     546}
     547
    431548MRB_API const char*
    432 mrb_sym2name(mrb_state *mrb, mrb_sym sym)
    433 {
    434   mrb_int len;
    435   const char *name = mrb_sym2name_len(mrb, sym, &len);
    436 
    437   if (!name) return NULL;
    438   if (symname_p(name) && strlen(name) == (size_t)len) {
    439     return name;
    440   }
    441   else {
    442     mrb_value str = mrb_str_dump(mrb, mrb_str_new_static(mrb, name, len));
    443     return RSTRING_PTR(str);
    444   }
     549mrb_sym_name(mrb_state *mrb, mrb_sym sym)
     550{
     551  return sym_name(mrb, sym, FALSE);
     552}
     553
     554MRB_API const char*
     555mrb_sym_dump(mrb_state *mrb, mrb_sym sym)
     556{
     557  return sym_name(mrb, sym, TRUE);
    445558}
    446559
     
    454567
    455568  mrb_get_args(mrb, "o", &s2);
    456   if (mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value();
     569  if (!mrb_symbol_p(s2)) return mrb_nil_value();
    457570  sym1 = mrb_symbol(s1);
    458571  sym2 = mrb_symbol(s2);
     
    462575    int retval;
    463576    mrb_int len, len1, len2;
    464 
    465     p1 = mrb_sym2name_len(mrb, sym1, &len1);
    466     p2 = mrb_sym2name_len(mrb, sym2, &len2);
     577    char buf1[8], buf2[8];
     578
     579    p1 = sym2name_len(mrb, sym1, buf1, &len1);
     580    p2 = sym2name_len(mrb, sym2, buf2, &len2);
    467581    len = lesser(len1, len2);
    468582    retval = memcmp(p1, p2, len);
     
    482596  struct RClass *sym;
    483597
    484   mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class);                 /* 15.2.11 */
     598  mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class);  /* 15.2.11 */
    485599  MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL);
    486600  mrb_undef_class_method(mrb,  sym, "new");
    487601
    488   mrb_define_method(mrb, sym, "===",             sym_equal,      MRB_ARGS_REQ(1));              /* 15.2.11.3.1  */
    489   mrb_define_method(mrb, sym, "id2name",         mrb_sym_to_s,   MRB_ARGS_NONE());              /* 15.2.11.3.2  */
    490   mrb_define_method(mrb, sym, "to_s",            mrb_sym_to_s,   MRB_ARGS_NONE());              /* 15.2.11.3.3  */
    491   mrb_define_method(mrb, sym, "to_sym",          sym_to_sym,     MRB_ARGS_NONE());              /* 15.2.11.3.4  */
    492   mrb_define_method(mrb, sym, "inspect",         sym_inspect,    MRB_ARGS_NONE());              /* 15.2.11.3.5(x)  */
    493   mrb_define_method(mrb, sym, "<=>",             sym_cmp,        MRB_ARGS_REQ(1));
    494 }
     602  mrb_define_method(mrb, sym, "id2name", sym_to_s,    MRB_ARGS_NONE());          /* 15.2.11.3.2 */
     603  mrb_define_method(mrb, sym, "to_s",    sym_to_s,    MRB_ARGS_NONE());          /* 15.2.11.3.3 */
     604  mrb_define_method(mrb, sym, "to_sym",  sym_to_sym,  MRB_ARGS_NONE());          /* 15.2.11.3.4 */
     605  mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE());          /* 15.2.11.3.5(x) */
     606  mrb_define_method(mrb, sym, "<=>",     sym_cmp,     MRB_ARGS_REQ(1));
     607}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/variable.c

    r331 r439  
    1010#include <mruby/proc.h>
    1111#include <mruby/string.h>
    12 
    13 typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
    14 
    15 #ifdef MRB_USE_IV_SEGLIST
    16 
    17 #ifndef MRB_SEGMENT_SIZE
    18 #define MRB_SEGMENT_SIZE 4
     12#include <mruby/variable.h>
     13
     14#ifndef MRB_IV_SEGMENT_SIZE
     15#define MRB_IV_SEGMENT_SIZE 4
    1916#endif
    2017
    2118typedef struct segment {
    22   mrb_sym key[MRB_SEGMENT_SIZE];
    23   mrb_value val[MRB_SEGMENT_SIZE];
     19  mrb_sym key[MRB_IV_SEGMENT_SIZE];
     20  mrb_value val[MRB_IV_SEGMENT_SIZE];
    2421  struct segment *next;
    2522} segment;
     
    3229} iv_tbl;
    3330
    34 /*
    35  * Creates the instance variable table.
    36  *
    37  * Parameters
    38  *   mrb
    39  * Returns
    40  *   the instance variable table.
    41  */
     31/* Creates the instance variable table. */
    4232static iv_tbl*
    4333iv_new(mrb_state *mrb)
     
    5343}
    5444
    55 /*
    56  * Set the value for the symbol in the instance variable table.
    57  *
    58  * Parameters
    59  *   mrb
    60  *   t     the instance variable table to be set in.
    61  *   sym   the symbol to be used as the key.
    62  *   val   the value to be set.
    63  */
     45/* Set the value for the symbol in the instance variable table. */
    6446static void
    6547iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
    6648{
    67   segment *seg = t->rootseg;
     49  segment *seg;
    6850  segment *prev = NULL;
    6951  segment *matched_seg = NULL;
     
    7153  size_t i;
    7254
     55  if (t == NULL) return;
     56  seg = t->rootseg;
    7357  while (seg) {
    74     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     58    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    7559      mrb_sym key = seg->key[i];
    7660      /* Found room in last segment after last_len */
     
    9680
    9781  /* Not found */
    98   t->size++;
    9982  if (matched_seg) {
    10083    matched_seg->key[matched_idx] = sym;
    10184    matched_seg->val[matched_idx] = val;
     85    t->size++;
    10286    return;
    10387  }
    10488
    10589  seg = (segment*)mrb_malloc(mrb, sizeof(segment));
    106   if (!seg) return;
    10790  seg->next = NULL;
    10891  seg->key[0] = sym;
    10992  seg->val[0] = val;
    11093  t->last_len = 1;
     94  t->size++;
    11195  if (prev) {
    11296    prev->next = seg;
     
    117101}
    118102
    119 /*
    120  * Get a value for a symbol from the instance variable table.
    121  *
    122  * Parameters
    123  *   mrb
    124  *   t     the variable table to be searched.
    125  *   sym   the symbol to be used as the key.
    126  *   vp    the value pointer. Receives the value if the specified symbol is
    127  *         contained in the instance variable table.
    128  * Returns
    129  *   true if the specified symbol is contained in the instance variable table.
    130  */
     103/* Get a value for a symbol from the instance variable table. */
    131104static mrb_bool
    132105iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
     
    135108  size_t i;
    136109
     110  if (t == NULL) return FALSE;
    137111  seg = t->rootseg;
    138112  while (seg) {
    139     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     113    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    140114      mrb_sym key = seg->key[i];
    141115
     
    153127}
    154128
    155 /*
    156  * Deletes the value for the symbol from the instance variable table.
    157  *
    158  * Parameters
    159  *   t    the variable table to be searched.
    160  *   sym  the symbol to be used as the key.
    161  *   vp   the value pointer. Receive the deleted value if the symbol is
    162  *        contained in the instance variable table.
    163  * Returns
    164  *   true if the specified symbol is contained in the instance variable table.
    165  */
     129/* Deletes the value for the symbol from the instance variable table. */
    166130static mrb_bool
    167131iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
     
    170134  size_t i;
    171135
     136  if (t == NULL) return FALSE;
    172137  seg = t->rootseg;
    173138  while (seg) {
    174     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     139    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    175140      mrb_sym key = seg->key[i];
    176141
     
    190155}
    191156
    192 static mrb_bool
    193 iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
     157/* Iterates over the instance variable table. */
     158static void
     159iv_foreach(mrb_state *mrb, iv_tbl *t, mrb_iv_foreach_func *func, void *p)
    194160{
    195161  segment *seg;
    196162  size_t i;
    197   int n;
    198 
     163
     164  if (t == NULL) return;
    199165  seg = t->rootseg;
    200166  while (seg) {
    201     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     167    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    202168      mrb_sym key = seg->key[i];
    203169
    204170      /* no value in last segment after last_len */
    205171      if (!seg->next && i >= t->last_len) {
    206         return FALSE;
     172        return;
    207173      }
    208174      if (key != 0) {
    209         n =(*func)(mrb, key, seg->val[i], p);
    210         if (n > 0) return FALSE;
    211         if (n < 0) {
    212           t->size--;
    213           seg->key[i] = 0;
     175        if ((*func)(mrb, key, seg->val[i], p) != 0) {
     176          return;
    214177        }
    215178      }
     
    217180    seg = seg->next;
    218181  }
    219   return TRUE;
    220 }
    221 
     182  return;
     183}
     184
     185/* Get the size of the instance variable table. */
    222186static size_t
    223187iv_size(mrb_state *mrb, iv_tbl *t)
     
    226190  size_t size = 0;
    227191
    228   if (!t) return 0;
     192  if (t == NULL) return 0;
    229193  if (t->size > 0) return t->size;
    230194  seg = t->rootseg;
     
    235199    }
    236200    seg = seg->next;
    237     size += MRB_SEGMENT_SIZE;
     201    size += MRB_IV_SEGMENT_SIZE;
    238202  }
    239203  /* empty iv_tbl */
     
    241205}
    242206
     207/* Copy the instance variable table. */
    243208static iv_tbl*
    244209iv_copy(mrb_state *mrb, iv_tbl *t)
     
    253218
    254219  while (seg != NULL) {
    255     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     220    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    256221      mrb_sym key = seg->key[i];
    257222      mrb_value val = seg->val[i];
     
    267232}
    268233
     234/* Free memory of the instance variable table. */
    269235static void
    270236iv_free(mrb_state *mrb, iv_tbl *t)
     
    281247}
    282248
    283 #else
    284 
    285 #include <mruby/khash.h>
    286 
    287 #ifndef MRB_IVHASH_INIT_SIZE
    288 #define MRB_IVHASH_INIT_SIZE 8
    289 #endif
    290 
    291 KHASH_DECLARE(iv, mrb_sym, mrb_value, TRUE)
    292 KHASH_DEFINE(iv, mrb_sym, mrb_value, TRUE, kh_int_hash_func, kh_int_hash_equal)
    293 
    294 typedef struct iv_tbl {
    295   khash_t(iv) h;
    296 } iv_tbl;
    297 
    298 static iv_tbl*
    299 iv_new(mrb_state *mrb)
    300 {
    301   return (iv_tbl*)kh_init_size(iv, mrb, MRB_IVHASH_INIT_SIZE);
    302 }
    303 
    304 static void
    305 iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
    306 {
    307   khash_t(iv) *h = &t->h;
    308   khiter_t k;
    309 
    310   k = kh_put(iv, mrb, h, sym);
    311   kh_value(h, k) = val;
    312 }
    313 
    314 static mrb_bool
    315 iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
    316 {
    317   khash_t(iv) *h = &t->h;
    318   khiter_t k;
    319 
    320   k = kh_get(iv, mrb, h, sym);
    321   if (k != kh_end(h)) {
    322     if (vp) *vp = kh_value(h, k);
    323     return TRUE;
    324   }
    325   return FALSE;
    326 }
    327 
    328 static mrb_bool
    329 iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
    330 {
    331   khash_t(iv) *h = &t->h;
    332   khiter_t k;
    333 
    334   if (h) {
    335     k = kh_get(iv, mrb, h, sym);
    336     if (k != kh_end(h)) {
    337       mrb_value val = kh_value(h, k);
    338       kh_del(iv, mrb, h, k);
    339       if (vp) *vp = val;
    340       return TRUE;
    341     }
    342   }
    343   return FALSE;
    344 }
    345 
    346 static mrb_bool
    347 iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
    348 {
    349   khash_t(iv) *h = &t->h;
    350   khiter_t k;
    351   int n;
    352 
    353   if (h) {
    354     for (k = kh_begin(h); k != kh_end(h); k++) {
    355       if (kh_exist(h, k)) {
    356         n = (*func)(mrb, kh_key(h, k), kh_value(h, k), p);
    357         if (n > 0) return FALSE;
    358         if (n < 0) {
    359           kh_del(iv, mrb, h, k);
    360         }
    361       }
    362     }
    363   }
    364   return TRUE;
    365 }
    366 
    367 static size_t
    368 iv_size(mrb_state *mrb, iv_tbl *t)
    369 {
    370   khash_t(iv) *h;
    371 
    372   if (t && (h = &t->h)) {
    373     return kh_size(h);
    374   }
    375   return 0;
    376 }
    377 
    378 static iv_tbl*
    379 iv_copy(mrb_state *mrb, iv_tbl *t)
    380 {
    381   return (iv_tbl*)kh_copy(iv, mrb, &t->h);
    382 }
    383 
    384 static void
    385 iv_free(mrb_state *mrb, iv_tbl *t)
    386 {
    387   kh_destroy(iv, mrb, &t->h);
    388 }
    389 
    390 #endif
    391 
    392249static int
    393250iv_mark_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
     
    400257mark_tbl(mrb_state *mrb, iv_tbl *t)
    401258{
    402   if (t) {
    403     iv_foreach(mrb, t, iv_mark_i, 0);
    404   }
     259  iv_foreach(mrb, t, iv_mark_i, 0);
    405260}
    406261
     
    485340}
    486341
     342static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
     343
     344void
     345mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
     346{
     347  assign_class_name(mrb, obj, sym, v);
     348  if (!obj->iv) {
     349    obj->iv = iv_new(mrb);
     350  }
     351  iv_put(mrb, obj->iv, sym, v);
     352  mrb_write_barrier(mrb, (struct RBasic*)obj);
     353}
     354
    487355MRB_API void
    488356mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
    489357{
    490   iv_tbl *t = obj->iv;
    491 
    492   if (MRB_FROZEN_P(obj)) {
    493     mrb_raisef(mrb, E_RUNTIME_ERROR, "can't modify frozen %S", mrb_obj_value(obj));
    494   }
    495   if (!t) {
    496     t = obj->iv = iv_new(mrb);
    497   }
    498   mrb_write_barrier(mrb, (struct RBasic*)obj);
    499   iv_put(mrb, t, sym, v);
    500 }
    501 
    502 MRB_API void
    503 mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
    504 {
    505   iv_tbl *t = obj->iv;
    506 
    507   if (!t) {
    508     t = obj->iv = iv_new(mrb);
    509   }
    510   else if (iv_get(mrb, t, sym, &v)) {
    511     return;
    512   }
    513   mrb_write_barrier(mrb, (struct RBasic*)obj);
    514   iv_put(mrb, t, sym, v);
     358  mrb_check_frozen(mrb, obj);
     359  mrb_obj_iv_set_force(mrb, obj, sym, v);
     360}
     361
     362/* Iterates over the instance variable table. */
     363MRB_API void
     364mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p)
     365{
     366  if (!obj_iv_p(obj)) return;
     367  iv_foreach(mrb, mrb_obj_ptr(obj)->iv, func, p);
     368}
     369
     370static inline mrb_bool
     371namespace_p(enum mrb_vtype tt)
     372{
     373  return tt == MRB_TT_CLASS || tt == MRB_TT_MODULE ? TRUE : FALSE;
     374}
     375
     376static inline void
     377assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
     378{
     379  if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) {
     380    struct RObject *c = mrb_obj_ptr(v);
     381    if (obj != c && ISUPPER(mrb_sym_name_len(mrb, sym, NULL)[0])) {
     382      mrb_sym id_classname = mrb_intern_lit(mrb, "__classname__");
     383      mrb_value o = mrb_obj_iv_get(mrb, c, id_classname);
     384
     385      if (mrb_nil_p(o)) {
     386        mrb_sym id_outer = mrb_intern_lit(mrb, "__outer__");
     387        o = mrb_obj_iv_get(mrb, c, id_outer);
     388
     389        if (mrb_nil_p(o)) {
     390          if ((struct RClass *)obj == mrb->object_class) {
     391            mrb_obj_iv_set_force(mrb, c, id_classname, mrb_symbol_value(sym));
     392          }
     393          else {
     394            mrb_obj_iv_set_force(mrb, c, id_outer, mrb_obj_value(obj));
     395          }
     396        }
     397      }
     398    }
     399  }
    515400}
    516401
     
    545430}
    546431
    547 #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
    548 
    549432MRB_API mrb_bool
    550 mrb_iv_p(mrb_state *mrb, mrb_sym iv_name)
     433mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym iv_name)
    551434{
    552435  const char *s;
    553   mrb_int i, len;
    554 
    555   s = mrb_sym2name_len(mrb, iv_name, &len);
     436  mrb_int len;
     437
     438  s = mrb_sym_name_len(mrb, iv_name, &len);
    556439  if (len < 2) return FALSE;
    557440  if (s[0] != '@') return FALSE;
    558   if (s[1] == '@') return FALSE;
    559   for (i=1; i<len; i++) {
    560     if (!identchar(s[i])) return FALSE;
    561   }
    562   return TRUE;
    563 }
    564 
    565 MRB_API void
    566 mrb_iv_check(mrb_state *mrb, mrb_sym iv_name)
    567 {
    568   if (!mrb_iv_p(mrb, iv_name)) {
    569     mrb_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name));
     441  if (ISDIGIT(s[1])) return FALSE;
     442  return mrb_ident_p(s+1, len-1);
     443}
     444
     445MRB_API void
     446mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym iv_name)
     447{
     448  if (!mrb_iv_name_sym_p(mrb, iv_name)) {
     449    mrb_name_error(mrb, iv_name, "'%n' is not allowed as an instance variable name", iv_name);
    570450  }
    571451}
     
    604484    mrb_str_cat_lit(mrb, str, ", ");
    605485  }
    606   s = mrb_sym2name_len(mrb, sym, &len);
     486  s = mrb_sym_name_len(mrb, sym, &len);
    607487  mrb_str_cat(mrb, str, s, len);
    608488  mrb_str_cat_lit(mrb, str, "=");
    609   if (mrb_type(v) == MRB_TT_OBJECT) {
     489  if (mrb_object_p(v)) {
    610490    ins = mrb_any_to_s(mrb, v);
    611491  }
     
    625505  if (len > 0) {
    626506    const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj));
    627     mrb_value str = mrb_str_buf_new(mrb, 30);
     507    mrb_value str = mrb_str_new_capa(mrb, 30);
    628508
    629509    mrb_str_cat_lit(mrb, str, "-<");
    630510    mrb_str_cat_cstr(mrb, str, cn);
    631511    mrb_str_cat_lit(mrb, str, ":");
    632     mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj));
     512    mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, obj));
    633513
    634514    iv_foreach(mrb, t, inspect_i, &str);
     
    646526    mrb_value val;
    647527
    648     if (t && iv_del(mrb, t, sym, &val)) {
     528    mrb_check_frozen(mrb, mrb_obj_ptr(obj));
     529    if (iv_del(mrb, t, sym, &val)) {
    649530      return val;
    650531    }
    651532  }
    652533  return mrb_undef_value();
    653 }
    654 
    655 mrb_value
    656 mrb_vm_iv_get(mrb_state *mrb, mrb_sym sym)
    657 {
    658   /* get self */
    659   return mrb_iv_get(mrb, mrb->c->stack[0], sym);
    660 }
    661 
    662 void
    663 mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
    664 {
    665   /* get self */
    666   mrb_iv_set(mrb, mrb->c->stack[0], sym, v);
    667534}
    668535
     
    675542
    676543  ary = *(mrb_value*)p;
    677   s = mrb_sym2name_len(mrb, sym, &len);
     544  s = mrb_sym_name_len(mrb, sym, &len);
    678545  if (len > 1 && s[0] == '@' && s[1] != '@') {
    679546    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     
    705572
    706573  ary = mrb_ary_new(mrb);
    707   if (obj_iv_p(self) && mrb_obj_ptr(self)->iv) {
     574  if (obj_iv_p(self)) {
    708575    iv_foreach(mrb, mrb_obj_ptr(self)->iv, iv_i, &ary);
    709576  }
     
    719586
    720587  ary = *(mrb_value*)p;
    721   s = mrb_sym2name_len(mrb, sym, &len);
     588  s = mrb_sym_name_len(mrb, sym, &len);
    722589  if (len > 2 && s[0] == '@' && s[1] == '@') {
    723590    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     
    729596/*
    730597 *  call-seq:
    731  *     mod.class_variables   -> array
     598 *     mod.class_variables(inherit=true)   -> array
    732599 *
    733600 *  Returns an array of the names of class variables in <i>mod</i>.
     
    747614  mrb_value ary;
    748615  struct RClass *c;
    749 
     616  mrb_bool inherit = TRUE;
     617
     618  mrb_get_args(mrb, "|b", &inherit);
    750619  ary = mrb_ary_new(mrb);
    751620  c = mrb_class_ptr(mod);
    752621  while (c) {
    753     if (c->iv) {
    754       iv_foreach(mrb, c->iv, cv_i, &ary);
    755     }
     622    iv_foreach(mrb, c->iv, cv_i, &ary);
     623    if (!inherit) break;
    756624    c = c->super;
    757625  }
     
    759627}
    760628
    761 MRB_API mrb_value
     629mrb_value
    762630mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
    763631{
     
    790658    }
    791659  }
    792   mrb_name_error(mrb, sym, "uninitialized class variable %S in %S",
    793                  mrb_sym2str(mrb, sym), mrb_obj_value(cls));
     660  mrb_name_error(mrb, sym, "uninitialized class variable %n in %C", sym, cls);
    794661  /* not reached */
    795662  return mrb_nil_value();
     
    808675
    809676  while (c) {
    810     if (c->iv) {
    811       iv_tbl *t = c->iv;
    812 
    813       if (iv_get(mrb, t, sym, NULL)) {
    814         mrb_write_barrier(mrb, (struct RBasic*)c);
    815         iv_put(mrb, t, sym, v);
    816         return;
    817       }
     677    iv_tbl *t = c->iv;
     678
     679    if (iv_get(mrb, t, sym, NULL)) {
     680      mrb_check_frozen(mrb, c);
     681      iv_put(mrb, t, sym, v);
     682      mrb_write_barrier(mrb, (struct RBasic*)c);
     683      return;
    818684    }
    819685    c = c->super;
     
    840706  }
    841707
     708  mrb_check_frozen(mrb, c);
    842709  if (!c->iv) {
    843710    c->iv = iv_new(mrb);
    844711  }
    845712
     713  iv_put(mrb, c->iv, sym, v);
    846714  mrb_write_barrier(mrb, (struct RBasic*)c);
    847   iv_put(mrb, c->iv, sym, v);
    848715}
    849716
     
    854721}
    855722
    856 MRB_API mrb_bool
     723mrb_bool
    857724mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym)
    858725{
    859726  while (c) {
    860     if (c->iv) {
    861       iv_tbl *t = c->iv;
    862       if (iv_get(mrb, t, sym, NULL)) return TRUE;
    863     }
     727    iv_tbl *t = c->iv;
     728    if (iv_get(mrb, t, sym, NULL)) return TRUE;
    864729    c = c->super;
    865730  }
     
    877742mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
    878743{
    879   struct RClass *c = mrb->c->ci->proc->target_class;
    880 
    881   if (!c) c = mrb->c->ci->target_class;
    882 
     744  struct RClass *c;
     745
     746  struct RProc *p = mrb->c->ci->proc;
     747
     748  for (;;) {
     749    c = MRB_PROC_TARGET_CLASS(p);
     750    if (c->tt != MRB_TT_SCLASS) break;
     751    p = p->upper;
     752  }
    883753  return mrb_mod_cv_get(mrb, c, sym);
    884754}
     
    887757mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
    888758{
    889   struct RClass *c = mrb->c->ci->proc->target_class;
    890 
    891   if (!c) c = mrb->c->ci->target_class;
     759  struct RClass *c;
     760  struct RProc *p = mrb->c->ci->proc;
     761
     762  for (;;) {
     763    c = MRB_PROC_TARGET_CLASS(p);
     764    if (c->tt != MRB_TT_SCLASS) break;
     765    p = p->upper;
     766  }
    892767  mrb_mod_cv_set(mrb, c, sym, v);
    893768}
     
    912787  struct RClass *c = base;
    913788  mrb_value v;
    914   iv_tbl *t;
    915789  mrb_bool retry = FALSE;
    916790  mrb_value name;
     
    919793  while (c) {
    920794    if (c->iv) {
    921       t = c->iv;
    922       if (iv_get(mrb, t, sym, &v))
     795      if (iv_get(mrb, c->iv, sym, &v))
    923796        return v;
    924797    }
    925798    c = c->super;
    926799  }
    927   if (!retry && base && base->tt == MRB_TT_MODULE) {
     800  if (!retry && base->tt == MRB_TT_MODULE) {
    928801    c = mrb->object_class;
    929802    retry = TRUE;
     
    944817mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
    945818{
    946   struct RClass *c = mrb->c->ci->proc->target_class;
    947 
    948   if (!c) c = mrb->c->ci->target_class;
    949   if (c) {
    950     struct RClass *c2;
    951     mrb_value v;
    952 
    953     if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
     819  struct RClass *c;
     820  struct RClass *c2;
     821  mrb_value v;
     822  struct RProc *proc;
     823
     824  c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
     825  if (iv_get(mrb, c->iv, sym, &v)) {
     826    return v;
     827  }
     828  c2 = c;
     829  while (c2 && c2->tt == MRB_TT_SCLASS) {
     830    mrb_value klass;
     831
     832    if (!iv_get(mrb, c2->iv, mrb_intern_lit(mrb, "__attached__"), &klass)) {
     833      c2 = NULL;
     834      break;
     835    }
     836    c2 = mrb_class_ptr(klass);
     837  }
     838  if (c2 && (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE)) c = c2;
     839  mrb_assert(!MRB_PROC_CFUNC_P(mrb->c->ci->proc));
     840  proc = mrb->c->ci->proc;
     841  while (proc) {
     842    c2 = MRB_PROC_TARGET_CLASS(proc);
     843    if (c2 && iv_get(mrb, c2->iv, sym, &v)) {
    954844      return v;
    955845    }
    956     c2 = c;
    957     while (c2 && c2->tt == MRB_TT_SCLASS) {
    958       mrb_value klass;
    959       klass = mrb_obj_iv_get(mrb, (struct RObject *)c2,
    960                              mrb_intern_lit(mrb, "__attached__"));
    961       c2 = mrb_class_ptr(klass);
    962     }
    963     if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2;
    964     c2 = c;
    965     for (;;) {
    966       c2 = mrb_class_outer_module(mrb, c2);
    967       if (!c2) break;
    968       if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) {
    969         return v;
    970       }
    971     }
     846    proc = proc->upper;
    972847  }
    973848  return const_get(mrb, c, sym);
     
    978853{
    979854  mod_const_check(mrb, mod);
     855  if (mrb_type(v) == MRB_TT_CLASS || mrb_type(v) == MRB_TT_MODULE) {
     856    mrb_class_name_class(mrb, mrb_class_ptr(mod), mrb_class_ptr(v), sym);
     857  }
    980858  mrb_iv_set(mrb, mod, sym, v);
    981859}
     
    984862mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
    985863{
    986   struct RClass *c = mrb->c->ci->proc->target_class;
    987 
    988   if (!c) c = mrb->c->ci->target_class;
     864  struct RClass *c;
     865
     866  c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
    989867  mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v);
    990868}
     
    1017895
    1018896  ary = *(mrb_value*)p;
    1019   s = mrb_sym2name_len(mrb, sym, &len);
     897  s = mrb_sym_name_len(mrb, sym, &len);
    1020898  if (len >= 1 && ISUPPER(s[0])) {
    1021     mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     899    mrb_int i, alen = RARRAY_LEN(ary);
     900
     901    for (i=0; i<alen; i++) {
     902      if (mrb_symbol(RARRAY_PTR(ary)[i]) == sym)
     903        break;
     904    }
     905    if (i==alen) {
     906      mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     907    }
    1022908  }
    1023909  return 0;
     
    1041927  ary = mrb_ary_new(mrb);
    1042928  while (c) {
    1043     if (c->iv) {
    1044       iv_foreach(mrb, c->iv, const_i, &ary);
    1045     }
     929    iv_foreach(mrb, c->iv, const_i, &ary);
    1046930    if (!inherit) break;
    1047931    c = c->super;
     
    1056940  mrb_value v;
    1057941
    1058   if (!mrb->globals) {
    1059     return mrb_nil_value();
    1060   }
    1061942  if (iv_get(mrb, mrb->globals, sym, &v))
    1062943    return v;
     
    1070951
    1071952  if (!mrb->globals) {
    1072     t = mrb->globals = iv_new(mrb);
    1073   }
    1074   else {
    1075     t = mrb->globals;
    1076   }
     953    mrb->globals = iv_new(mrb);
     954  }
     955  t = mrb->globals;
    1077956  iv_put(mrb, t, sym, v);
    1078957}
     
    1081960mrb_gv_remove(mrb_state *mrb, mrb_sym sym)
    1082961{
    1083   if (!mrb->globals) {
    1084     return;
    1085   }
    1086962  iv_del(mrb, mrb->globals, sym, NULL);
    1087963}
     
    1112988  iv_tbl *t = mrb->globals;
    1113989  mrb_value ary = mrb_ary_new(mrb);
    1114   size_t i;
    1115   char buf[3];
    1116 
    1117   if (t) {
    1118     iv_foreach(mrb, t, gv_i, &ary);
    1119   }
    1120   buf[0] = '$';
    1121   buf[2] = 0;
    1122   for (i = 1; i <= 9; ++i) {
    1123     buf[1] = (char)(i + '0');
    1124     mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2)));
    1125   }
     990
     991  iv_foreach(mrb, t, gv_i, &ary);
    1126992  return ary;
    1127993}
     
    1132998  struct RClass *klass = mrb_class_ptr(mod);
    1133999  struct RClass *tmp;
    1134   mrb_bool mod_retry = 0;
     1000  mrb_bool mod_retry = FALSE;
    11351001
    11361002  tmp = klass;
    11371003retry:
    11381004  while (tmp) {
    1139     if (tmp->iv && iv_get(mrb, tmp->iv, id, NULL)) {
     1005    if (iv_get(mrb, tmp->iv, id, NULL)) {
    11401006      return TRUE;
    11411007    }
     
    11441010  }
    11451011  if (!exclude && !mod_retry && (klass->tt == MRB_TT_MODULE)) {
    1146     mod_retry = 1;
     1012    mod_retry = TRUE;
    11471013    tmp = mrb->object_class;
    11481014    goto retry;
     
    11871053}
    11881054
    1189 mrb_sym
    1190 mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer)
    1191 {
    1192   mrb_value name;
    1193 
    1194   name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__classid__"));
    1195   if (mrb_nil_p(name)) {
    1196 
    1197     if (!outer) return 0;
    1198     else {
    1199       struct csym_arg arg;
    1200 
    1201       arg.c = c;
    1202       arg.sym = 0;
    1203       iv_foreach(mrb, outer->iv, csym_i, &arg);
    1204       return arg.sym;
    1205     }
    1206   }
    1207   return mrb_symbol(name);
    1208 }
     1055static mrb_sym
     1056find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c)
     1057{
     1058  struct csym_arg arg;
     1059
     1060  if (!outer) return 0;
     1061  if (outer == c) return 0;
     1062  arg.c = c;
     1063  arg.sym = 0;
     1064  iv_foreach(mrb, outer->iv, csym_i, &arg);
     1065  return arg.sym;
     1066}
     1067
     1068static struct RClass*
     1069outer_class(mrb_state *mrb, struct RClass *c)
     1070{
     1071  mrb_value ov;
     1072
     1073  ov = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
     1074  if (mrb_nil_p(ov)) return NULL;
     1075  switch (mrb_type(ov)) {
     1076  case MRB_TT_CLASS:
     1077  case MRB_TT_MODULE:
     1078    return mrb_class_ptr(ov);
     1079  default:
     1080    break;
     1081  }
     1082  return NULL;
     1083}
     1084
     1085static mrb_bool
     1086detect_outer_loop(mrb_state *mrb, struct RClass *c)
     1087{
     1088  struct RClass *t = c;         /* tortoise */
     1089  struct RClass *h = c;         /* hare */
     1090
     1091  for (;;) {
     1092    if (h == NULL) return FALSE;
     1093    h = outer_class(mrb, h);
     1094    if (h == NULL) return FALSE;
     1095    h = outer_class(mrb, h);
     1096    t = outer_class(mrb, t);
     1097    if (t == h) return TRUE;
     1098  }
     1099}
     1100
     1101mrb_value
     1102mrb_class_find_path(mrb_state *mrb, struct RClass *c)
     1103{
     1104  struct RClass *outer;
     1105  mrb_value path;
     1106  mrb_sym name;
     1107  const char *str;
     1108  mrb_int len;
     1109
     1110  if (detect_outer_loop(mrb, c)) return mrb_nil_value();
     1111  outer = outer_class(mrb, c);
     1112  if (outer == NULL) return mrb_nil_value();
     1113  name = find_class_sym(mrb, outer, c);
     1114  if (name == 0) return mrb_nil_value();
     1115  str = mrb_class_name(mrb, outer);
     1116  path = mrb_str_new_capa(mrb, 40);
     1117  mrb_str_cat_cstr(mrb, path, str);
     1118  mrb_str_cat_cstr(mrb, path, "::");
     1119
     1120  str = mrb_sym_name_len(mrb, name, &len);
     1121  mrb_str_cat(mrb, path, str, len);
     1122  if (RSTRING_PTR(path)[0] != '#') {
     1123    iv_del(mrb, c->iv, mrb_intern_lit(mrb, "__outer__"), NULL);
     1124    iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path);
     1125    mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path);
     1126    path = mrb_str_dup(mrb, path);
     1127  }
     1128  return path;
     1129}
     1130
     1131#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
     1132
     1133mrb_bool
     1134mrb_ident_p(const char *s, mrb_int len)
     1135{
     1136  mrb_int i;
     1137
     1138  for (i = 0; i < len; i++) {
     1139    if (!identchar(s[i])) return FALSE;
     1140  }
     1141  return TRUE;
     1142}
  • EcnlProtoTool/trunk/mruby-2.1.1/src/vm.c

    r331 r439  
    77#include <stddef.h>
    88#include <stdarg.h>
     9#ifndef MRB_WITHOUT_FLOAT
    910#include <math.h>
     11#endif
    1012#include <mruby.h>
    1113#include <mruby/array.h>
     
    2325#include <mruby/throw.h>
    2426
    25 #ifndef MRB_DISABLE_STDIO
     27#ifdef MRB_DISABLE_STDIO
    2628#if defined(__cplusplus)
    2729extern "C" {
     
    5254#ifndef MRB_FUNCALL_DEPTH_MAX
    5355#define MRB_FUNCALL_DEPTH_MAX 512
     56#endif
     57
     58/* Maximum depth of ecall() recursion. */
     59#ifndef MRB_ECALL_DEPTH_MAX
     60#define MRB_ECALL_DEPTH_MAX 512
    5461#endif
    5562
     
    6673#endif
    6774
    68 #define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
     75
     76#ifndef MRB_GC_FIXED_ARENA
     77static void
     78mrb_gc_arena_shrink(mrb_state *mrb, int idx)
     79{
     80  mrb_gc *gc = &mrb->gc;
     81  int capa = gc->arena_capa;
     82
     83  if (idx < capa / 4) {
     84    capa >>= 2;
     85    if (capa < MRB_GC_ARENA_SIZE) {
     86      capa = MRB_GC_ARENA_SIZE;
     87    }
     88    if (capa != gc->arena_capa) {
     89      gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa);
     90      gc->arena_capa = capa;
     91    }
     92  }
     93}
     94#else
     95#define mrb_gc_arena_shrink(mrb,idx)
     96#endif
    6997
    7098#define CALL_MAXARGS 127
     
    116144
    117145static inline void
    118 envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)
     146envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize)
    119147{
    120148  mrb_callinfo *ci = mrb->c->cibase;
     
    126154
    127155    if (e && MRB_ENV_STACK_SHARED_P(e) &&
    128         (st = e->stack) && oldbase <= st && st < oldbase+size) {
     156        (st = e->stack) && oldbase <= st && st < oldbase+oldsize) {
    129157      ptrdiff_t off = e->stack - oldbase;
    130158
    131159      e->stack = newbase + off;
    132160    }
     161
     162    if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) {
     163      e = MRB_PROC_ENV(ci->proc);
     164
     165      if (e && MRB_ENV_STACK_SHARED_P(e) &&
     166          (st = e->stack) && oldbase <= st && st < oldbase+oldsize) {
     167        ptrdiff_t off = e->stack - oldbase;
     168
     169        e->stack = newbase + off;
     170      }
     171    }
     172
    133173    ci->stackent = newbase + (ci->stackent - oldbase);
    134174    ci++;
     
    139179
    140180static void
    141 stack_extend_alloc(mrb_state *mrb, int room)
     181stack_extend_alloc(mrb_state *mrb, mrb_int room)
    142182{
    143183  mrb_value *oldbase = mrb->c->stbase;
     
    149189  if (off > size) size = off;
    150190#ifdef MRB_STACK_EXTEND_DOUBLING
    151   if (room <= size)
     191  if ((size_t)room <= size)
    152192    size *= 2;
    153193  else
     
    168208  }
    169209  stack_clear(&(newstack[oldsize]), size - oldsize);
    170   envadjust(mrb, oldbase, newstack, size);
     210  envadjust(mrb, oldbase, newstack, oldsize);
    171211  mrb->c->stbase = newstack;
    172212  mrb->c->stack = mrb->c->stbase + off;
     
    180220}
    181221
    182 static inline void
    183 stack_extend(mrb_state *mrb, int room)
     222MRB_API void
     223mrb_stack_extend(mrb_state *mrb, mrb_int room)
    184224{
    185225  if (mrb->c->stack + room >= mrb->c->stend) {
     
    191231uvenv(mrb_state *mrb, int up)
    192232{
    193   struct REnv *e = mrb->c->ci->proc->env;
     233  struct RProc *proc = mrb->c->ci->proc;
     234  struct REnv *e;
    194235
    195236  while (up--) {
    196     if (!e) return NULL;
    197     e = (struct REnv*)e->c;
    198   }
    199   return e;
    200 }
    201 
    202 static inline mrb_bool
    203 is_strict(mrb_state *mrb, struct REnv *e)
    204 {
    205   int cioff = e->cioff;
    206 
    207   if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc &&
    208       MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) {
    209     return TRUE;
    210   }
    211   return FALSE;
    212 }
    213 
    214 static inline struct REnv*
    215 top_env(mrb_state *mrb, struct RProc *proc)
    216 {
    217   struct REnv *e = proc->env;
    218 
    219   if (is_strict(mrb, e)) return e;
    220   while (e->c) {
    221     e = (struct REnv*)e->c;
    222     if (is_strict(mrb, e)) return e;
    223   }
    224   return e;
     237    proc = proc->upper;
     238    if (!proc) return NULL;
     239  }
     240  e = MRB_PROC_ENV(proc);
     241  if (e) return e;              /* proc has enclosed env */
     242  else {
     243    mrb_callinfo *ci = mrb->c->ci;
     244    mrb_callinfo *cb = mrb->c->cibase;
     245
     246    while (cb <= ci) {
     247      if (ci->proc == proc) {
     248        return ci->env;
     249      }
     250      ci--;
     251    }
     252  }
     253  return NULL;
     254}
     255
     256static inline struct RProc*
     257top_proc(mrb_state *mrb, struct RProc *proc)
     258{
     259  while (proc->upper) {
     260    if (MRB_PROC_SCOPE_P(proc) || MRB_PROC_STRICT_P(proc))
     261      return proc;
     262    proc = proc->upper;
     263  }
     264  return proc;
    225265}
    226266
     
    229269#define CI_ACC_RESUMED -3
    230270
    231 static mrb_callinfo*
     271static inline mrb_callinfo*
    232272cipush(mrb_state *mrb)
    233273{
    234274  struct mrb_context *c = mrb->c;
     275  static const mrb_callinfo ci_zero = { 0 };
    235276  mrb_callinfo *ci = c->ci;
    236277
     
    245286  }
    246287  ci = ++c->ci;
     288  *ci = ci_zero;
    247289  ci->epos = mrb->c->eidx;
    248290  ci->ridx = ridx;
    249   ci->env = 0;
    250   ci->pc = 0;
    251   ci->err = 0;
    252   ci->proc = 0;
    253   ci->acc = 0;
    254291
    255292  return ci;
    256293}
    257294
    258 MRB_API void
     295void
    259296mrb_env_unshare(mrb_state *mrb, struct REnv *e)
    260297{
    261   size_t len = (size_t)MRB_ENV_STACK_LEN(e);
    262   ptrdiff_t cioff = e->cioff;
    263   mrb_value *p;
    264 
    265   if (!MRB_ENV_STACK_SHARED_P(e)) return;
    266   if (e->cxt.c != mrb->c) return;
    267   if (e->cioff == 0 && e->cxt.c == mrb->root_c) return;
    268   MRB_ENV_UNSHARE_STACK(e);
    269   if (!e->c) {
    270     /* save block argument position (negated) */
    271     e->cioff = -e->cxt.c->cibase[cioff].argc-1;
    272   }
    273   e->cxt.mid = e->cxt.c->cibase[cioff].mid;
    274   p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
    275   if (len > 0) {
    276     stack_copy(p, e->stack, len);
    277   }
    278   e->stack = p;
    279   mrb_write_barrier(mrb, (struct RBasic *)e);
    280 }
    281 
    282 static void
     298  if (e == NULL) return;
     299  else {
     300    size_t len = (size_t)MRB_ENV_STACK_LEN(e);
     301    mrb_value *p;
     302
     303    if (!MRB_ENV_STACK_SHARED_P(e)) return;
     304    if (e->cxt != mrb->c) return;
     305    if (e == mrb->c->cibase->env) return; /* for mirb */
     306    p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
     307    if (len > 0) {
     308      stack_copy(p, e->stack, len);
     309    }
     310    e->stack = p;
     311    MRB_ENV_UNSHARE_STACK(e);
     312    mrb_write_barrier(mrb, (struct RBasic *)e);
     313  }
     314}
     315
     316static inline void
    283317cipop(mrb_state *mrb)
    284318{
     
    287321
    288322  c->ci--;
    289 
    290   if (env) {
    291     mrb_env_unshare(mrb, env);
    292   }
     323  if (env) mrb_env_unshare(mrb, env);
    293324}
    294325
     
    296327
    297328static void
    298 ecall(mrb_state *mrb, int i)
     329ecall(mrb_state *mrb)
    299330{
    300331  struct RProc *p;
    301   mrb_callinfo *ci = mrb->c->ci;
    302   mrb_value *self = mrb->c->stack;
     332  struct mrb_context *c = mrb->c;
     333  mrb_callinfo *ci = c->ci;
    303334  struct RObject *exc;
     335  struct REnv *env;
    304336  ptrdiff_t cioff;
    305337  int ai = mrb_gc_arena_save(mrb);
     338  uint16_t i = --c->eidx;
     339  int nregs;
    306340
    307341  if (i<0) return;
    308   if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
     342  /* restrict total call depth of ecall() */
     343  if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) {
    309344    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
    310345  }
    311   p = mrb->c->ensure[i];
     346  p = c->ensure[i];
    312347  if (!p) return;
    313   mrb->c->ensure[i] = NULL;
    314   cioff = ci - mrb->c->cibase;
     348  mrb_assert(!MRB_PROC_CFUNC_P(p));
     349  c->ensure[i] = NULL;
     350  nregs = p->upper->body.irep->nregs;
     351  if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc) &&
     352      ci->proc->body.irep->nregs > nregs) {
     353    nregs = ci->proc->body.irep->nregs;
     354  }
     355  cioff = ci - c->cibase;
    315356  ci = cipush(mrb);
    316357  ci->stackent = mrb->c->stack;
     
    319360  ci->argc = 0;
    320361  ci->proc = p;
    321   ci->nregs = p->body.irep->nregs;
    322   ci->target_class = p->target_class;
    323   mrb->c->stack = mrb->c->stack + ci[-1].nregs;
     362  ci->target_class = MRB_PROC_TARGET_CLASS(p);
     363  env = MRB_PROC_ENV(p);
     364  mrb_assert(env);
     365  c->stack += nregs;
    324366  exc = mrb->exc; mrb->exc = 0;
    325367  if (exc) {
    326368    mrb_gc_protect(mrb, mrb_obj_value(exc));
    327369  }
    328   mrb_run(mrb, p, *self);
    329   mrb->c->ci = mrb->c->cibase + cioff;
     370  if (mrb->c->fib) {
     371    mrb_gc_protect(mrb, mrb_obj_value(mrb->c->fib));
     372  }
     373  mrb_run(mrb, p, env->stack[0]);
     374  mrb->c = c;
     375  c->ci = c->cibase + cioff;
    330376  if (!mrb->exc) mrb->exc = exc;
    331377  mrb_gc_arena_restore(mrb, ai);
     378  mrb->ecall_nest--;
    332379}
    333380
     
    356403}
    357404
     405static int
     406ci_nregs(mrb_callinfo *ci)
     407{
     408  struct RProc *p;
     409  int n = 0;
     410
     411  if (!ci) return 3;
     412  p = ci->proc;
     413  if (!p) {
     414    if (ci->argc < 0) return 3;
     415    return ci->argc+2;
     416  }
     417  if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
     418    n = p->body.irep->nregs;
     419  }
     420  if (ci->argc < 0) {
     421    if (n < 3) n = 3; /* self + args + blk */
     422  }
     423  if (ci->argc > n) {
     424    n = ci->argc + 2; /* self + blk */
     425  }
     426  return n;
     427}
     428
    358429MRB_API mrb_value
    359430mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk)
    360431{
    361432  mrb_value val;
     433  int ai = mrb_gc_arena_save(mrb);
    362434
    363435  if (!mrb->jmp) {
     
    383455  }
    384456  else {
    385     struct RProc *p;
     457    mrb_method_t m;
    386458    struct RClass *c;
    387459    mrb_callinfo *ci;
    388     int n;
     460    int n = ci_nregs(mrb->c->ci);
    389461    ptrdiff_t voff = -1;
    390462
     
    392464      stack_init(mrb);
    393465    }
    394     n = mrb->c->ci->nregs;
    395466    if (argc < 0) {
    396       mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc));
     467      mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc);
    397468    }
    398469    c = mrb_class(mrb, self);
    399     p = mrb_method_search_vm(mrb, &c, mid);
    400     if (!p) {
     470    m = mrb_method_search_vm(mrb, &c, mid);
     471    if (MRB_METHOD_UNDEF_P(m)) {
    401472      mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    402473      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
    403       p = mrb_method_search_vm(mrb, &c, missing);
    404       if (!p) {
     474      m = mrb_method_search_vm(mrb, &c, missing);
     475      if (MRB_METHOD_UNDEF_P(m)) {
    405476        mrb_method_missing(mrb, mid, self, args);
    406477      }
    407478      mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
    408       stack_extend(mrb, n+2);
     479      mrb_stack_extend(mrb, n+2);
    409480      mrb->c->stack[n+1] = args;
    410481      argc = -1;
     
    415486    ci = cipush(mrb);
    416487    ci->mid = mid;
    417     ci->proc = p;
    418488    ci->stackent = mrb->c->stack;
    419     ci->argc = argc;
     489    ci->argc = (int)argc;
    420490    ci->target_class = c;
    421491    mrb->c->stack = mrb->c->stack + n;
     492    if (argc < 0) argc = 1;
    422493    if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
    423494      voff = argv - mrb->c->stbase;
    424495    }
    425     if (MRB_PROC_CFUNC_P(p)) {
    426       ci->nregs = argc + 2;
    427       stack_extend(mrb, ci->nregs);
    428     }
    429     else if (argc >= CALL_MAXARGS) {
     496    if (argc >= CALL_MAXARGS) {
    430497      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
    431       stack_extend(mrb, ci->nregs);
     498
    432499      mrb->c->stack[1] = args;
    433500      ci->argc = -1;
    434501      argc = 1;
    435502    }
    436     else {
    437       if (argc < 0) argc = 1;
    438       ci->nregs = p->body.irep->nregs + argc;
    439       stack_extend(mrb, ci->nregs);
     503    mrb_stack_extend(mrb, argc + 2);
     504    if (MRB_METHOD_PROC_P(m)) {
     505      struct RProc *p = MRB_METHOD_PROC(m);
     506
     507      ci->proc = p;
     508      if (!MRB_PROC_CFUNC_P(p)) {
     509        mrb_stack_extend(mrb, p->body.irep->nregs + argc);
     510      }
    440511    }
    441512    if (voff >= 0) {
     
    448519    mrb->c->stack[argc+1] = blk;
    449520
    450     if (MRB_PROC_CFUNC_P(p)) {
    451       int ai = mrb_gc_arena_save(mrb);
    452 
     521    if (MRB_METHOD_CFUNC_P(m)) {
    453522      ci->acc = CI_ACC_DIRECT;
    454       val = p->body.func(mrb, self);
     523      val = MRB_METHOD_CFUNC(m)(mrb, self);
    455524      mrb->c->stack = mrb->c->ci->stackent;
    456525      cipop(mrb);
    457       mrb_gc_arena_restore(mrb, ai);
    458526    }
    459527    else {
    460528      ci->acc = CI_ACC_SKIP;
    461       val = mrb_run(mrb, p, self);
    462     }
    463   }
     529      val = mrb_run(mrb, MRB_METHOD_PROC(m), self);
     530    }
     531  }
     532  mrb_gc_arena_restore(mrb, ai);
    464533  mrb_gc_protect(mrb, val);
    465534  return val;
     
    476545{
    477546  mrb_callinfo *ci = mrb->c->ci;
     547  int keep, nregs;
    478548
    479549  mrb->c->stack[0] = self;
    480550  ci->proc = p;
    481   ci->target_class = p->target_class;
    482551  if (MRB_PROC_CFUNC_P(p)) {
    483     return p->body.func(mrb, self);
    484   }
    485   if (ci->argc < 0) {
    486     stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs);
     552    return MRB_PROC_CFUNC(p)(mrb, self);
     553  }
     554  nregs = p->body.irep->nregs;
     555  if (ci->argc < 0) keep = 3;
     556  else keep = ci->argc + 2;
     557  if (nregs < keep) {
     558    mrb_stack_extend(mrb, keep);
    487559  }
    488560  else {
    489     stack_extend(mrb, p->body.irep->nregs);
    490   }
    491 
    492   ci->nregs = p->body.irep->nregs;
     561    mrb_stack_extend(mrb, nregs);
     562    stack_clear(mrb->c->stack+keep, nregs-keep);
     563  }
     564
    493565  ci = cipush(mrb);
    494   ci->nregs = 0;
    495566  ci->target_class = 0;
    496567  ci->pc = p->body.irep->iseq;
     
    520591 *     k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"
    521592 */
    522 MRB_API mrb_value
     593mrb_value
    523594mrb_f_send(mrb_state *mrb, mrb_value self)
    524595{
     
    526597  mrb_value block, *argv, *regs;
    527598  mrb_int argc, i, len;
    528   struct RProc *p;
     599  mrb_method_t m;
    529600  struct RClass *c;
    530601  mrb_callinfo *ci;
     
    538609
    539610  c = mrb_class(mrb, self);
    540   p = mrb_method_search_vm(mrb, &c, name);
    541 
    542   if (!p) {                     /* call method_mising */
     611  m = mrb_method_search_vm(mrb, &c, name);
     612  if (MRB_METHOD_UNDEF_P(m)) {            /* call method_mising */
    543613    goto funcall;
    544614  }
     
    558628  }
    559629
    560   return mrb_exec_irep(mrb, self, p);
     630  if (MRB_METHOD_CFUNC_P(m)) {
     631    if (MRB_METHOD_PROC_P(m)) {
     632      ci->proc = MRB_METHOD_PROC(m);
     633    }
     634    return MRB_METHOD_CFUNC(m)(mrb, self);
     635  }
     636  return mrb_exec_irep(mrb, self, MRB_METHOD_PROC(m));
    561637}
    562638
     
    566642  struct RProc *p;
    567643  mrb_callinfo *ci;
    568   mrb_int max = 3;
     644  int nregs;
    569645
    570646  if (mrb_nil_p(blk)) {
     
    582658  ci->mid = ci[-1].mid;
    583659  if (MRB_PROC_CFUNC_P(p)) {
    584     stack_extend(mrb, 3);
     660    mrb_stack_extend(mrb, 3);
    585661    mrb->c->stack[0] = self;
    586662    mrb->c->stack[1] = self;
    587663    mrb->c->stack[2] = mrb_nil_value();
    588     return p->body.func(mrb, self);
    589   }
    590   ci->nregs = p->body.irep->nregs;
    591   if (max < ci->nregs) max = ci->nregs;
    592   stack_extend(mrb, max);
     664    return MRB_PROC_CFUNC(p)(mrb, self);
     665  }
     666  nregs = p->body.irep->nregs;
     667  if (nregs < 3) nregs = 3;
     668  mrb_stack_extend(mrb, nregs);
    593669  mrb->c->stack[0] = self;
    594670  mrb->c->stack[1] = self;
    595   mrb->c->stack[2] = mrb_nil_value();
     671  stack_clear(mrb->c->stack+2, nregs-2);
    596672  ci = cipush(mrb);
    597   ci->nregs = 0;
    598673  ci->target_class = 0;
    599674  ci->pc = p->body.irep->iseq;
     
    659734  case MRB_TT_SYMBOL:
    660735  case MRB_TT_FIXNUM:
     736#ifndef MRB_WITHOUT_FLOAT
    661737  case MRB_TT_FLOAT:
     738#endif
    662739    c = 0;
    663740    break;
     
    676753  mrb_sym mid = mrb->c->ci->mid;
    677754  mrb_callinfo *ci;
    678   int n = mrb->c->ci->nregs;
    679755  mrb_value val;
     756  int n;
    680757
    681758  if (mrb_nil_p(b)) {
    682759    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    683760  }
    684   if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
     761  ci = mrb->c->ci;
     762  n = ci_nregs(ci);
     763  if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
    685764    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
    686765  }
     
    690769  ci->proc = p;
    691770  ci->stackent = mrb->c->stack;
    692   ci->argc = argc;
     771  ci->argc = (int)argc;
    693772  ci->target_class = c;
    694773  ci->acc = CI_ACC_SKIP;
     774  n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs;
    695775  mrb->c->stack = mrb->c->stack + n;
    696   if (MRB_PROC_CFUNC_P(p)) {
    697     ci->nregs = argc + 2;
    698     stack_extend(mrb, ci->nregs);
    699   }
    700   else {
    701     ci->nregs = p->body.irep->nregs;
    702     stack_extend(mrb, ci->nregs);
    703   }
     776  mrb_stack_extend(mrb, n);
    704777
    705778  mrb->c->stack[0] = self;
     
    710783
    711784  if (MRB_PROC_CFUNC_P(p)) {
    712     val = p->body.func(mrb, self);
     785    val = MRB_PROC_CFUNC(p)(mrb, self);
    713786    mrb->c->stack = mrb->c->ci->stackent;
     787    cipop(mrb);
    714788  }
    715789  else {
    716     int cioff = mrb->c->ci - mrb->c->cibase;
    717790    val = mrb_run(mrb, p, self);
    718     mrb->c->ci = mrb->c->cibase + cioff;
    719   }
    720   cipop(mrb);
     791  }
    721792  return val;
    722793}
     
    727798  struct RProc *p = mrb_proc_ptr(b);
    728799
    729   return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);
     800  return mrb_yield_with_class(mrb, b, argc, argv, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p));
    730801}
    731802
     
    735806  struct RProc *p = mrb_proc_ptr(b);
    736807
    737   return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
     808  return mrb_yield_with_class(mrb, b, 1, &arg, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p));
    738809}
    739810
     
    747818    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    748819  }
    749   if (mrb_type(b) != MRB_TT_PROC) {
     820  if (!mrb_proc_p(b)) {
    750821    mrb_raise(mrb, E_TYPE_ERROR, "not a block");
    751822  }
     
    754825  ci = mrb->c->ci;
    755826
    756   stack_extend(mrb, 3);
     827  mrb_stack_extend(mrb, 3);
    757828  mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
    758829  mrb->c->stack[2] = mrb_nil_value();
     
    767838
    768839  brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL);
    769   brk->iv = NULL;
    770   brk->proc = p;
    771   brk->val = val;
     840  mrb_break_proc_set(brk, p);
     841  mrb_break_value_set(brk, val);
    772842
    773843  return brk;
     
    789859  mrb_value exc;
    790860
    791   msg = mrb_str_buf_new(mrb, sizeof(lead) + 7);
     861  msg = mrb_str_new_capa(mrb, sizeof(lead) + 7);
    792862  mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1);
    793863  mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]);
     
    810880  }
    811881  if (mrb->c->ci->mid) {
    812     str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)",
    813                   mrb_sym2str(mrb, mrb->c->ci->mid),
    814                   mrb_fixnum_value(argc), mrb_fixnum_value(num));
     882    str = mrb_format(mrb, "'%n': wrong number of arguments (%i for %i)",
     883                     mrb->c->ci->mid, argc, num);
    815884  }
    816885  else {
    817     str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
    818                      mrb_fixnum_value(argc), mrb_fixnum_value(num));
     886    str = mrb_format(mrb, "wrong number of arguments (%i for %i)", argc, num);
    819887  }
    820888  exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str);
     
    822890}
    823891
    824 #define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc;
    825 #define ERR_PC_CLR(mrb)     mrb->c->ci->err = 0;
     892#define ERR_PC_SET(mrb) mrb->c->ci->err = pc0;
     893#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0;
    826894#ifdef MRB_ENABLE_DEBUG_HOOK
    827895#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs));
     
    836904#endif
    837905
    838 
     906#ifndef MRB_DISABLE_DIRECT_THREADING
    839907#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER
    840908#define DIRECT_THREADED
    841909#endif
     910#endif /* ifndef MRB_DISABLE_DIRECT_THREADING */
    842911
    843912#ifndef DIRECT_THREADED
    844913
    845 #define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
    846 #define CASE(op) case op:
    847 #define NEXT pc++; break
    848 #define JUMP break
     914#define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) {
     915#define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops ();; L_ ## insn ## _BODY:
     916#define NEXT break
     917#define JUMP NEXT
    849918#define END_DISPATCH }}
    850919
     
    852921
    853922#define INIT_DISPATCH JUMP; return mrb_nil_value();
    854 #define CASE(op) L_ ## op:
    855 #define NEXT i=BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
    856 #define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
     923#define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); L_ ## insn ## _BODY:
     924#define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn]
     925#define JUMP NEXT
    857926
    858927#define END_DISPATCH
     
    866935  mrb_value result;
    867936  struct mrb_context *c = mrb->c;
    868   int cioff = c->ci - c->cibase;
     937  ptrdiff_t cioff = c->ci - c->cibase;
    869938  unsigned int nregs = irep->nregs;
    870939
     
    874943  if (stack_keep > nregs)
    875944    nregs = stack_keep;
    876   stack_extend(mrb, nregs);
     945  mrb_stack_extend(mrb, nregs);
    877946  stack_clear(c->stack + stack_keep, nregs - stack_keep);
    878947  c->stack[0] = self;
    879948  result = mrb_vm_exec(mrb, proc, irep->iseq);
    880   if (c->ci - c->cibase > cioff) {
    881     c->ci = c->cibase + cioff;
    882   }
    883949  if (mrb->c != c) {
    884950    if (mrb->c->fib) {
     
    887953    mrb->c = c;
    888954  }
     955  else if (c->ci - c->cibase > cioff) {
     956    c->ci = c->cibase + cioff;
     957  }
    889958  return result;
    890959}
    891960
     961static mrb_bool
     962check_target_class(mrb_state *mrb)
     963{
     964  if (!mrb->c->ci->target_class) {
     965    mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
     966    mrb_exc_set(mrb, exc);
     967    return FALSE;
     968  }
     969  return TRUE;
     970}
     971
     972void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
     973
    892974MRB_API mrb_value
    893 mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
    894 {
    895   /* mrb_assert(mrb_proc_cfunc_p(proc)) */
     975mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *pc)
     976{
     977  /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */
     978  const mrb_code *pc0 = pc;
    896979  mrb_irep *irep = proc->body.irep;
    897980  mrb_value *pool = irep->pool;
    898981  mrb_sym *syms = irep->syms;
    899   mrb_code i;
     982  mrb_code insn;
    900983  int ai = mrb_gc_arena_save(mrb);
    901984  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
    902985  struct mrb_jmpbuf c_jmp;
     986  uint32_t a;
     987  uint16_t b;
     988  uint8_t c;
     989  mrb_sym mid;
    903990
    904991#ifdef DIRECT_THREADED
    905992  static void *optable[] = {
    906     &&L_OP_NOP, &&L_OP_MOVE,
    907     &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL,
    908     &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF,
    909     &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL,
    910     &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV,
    911     &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST,
    912     &&L_OP_GETUPVAR, &&L_OP_SETUPVAR,
    913     &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT,
    914     &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP,
    915     &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND,
    916     &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER,
    917     &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH,
    918     &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV,
    919     &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE,
    920     &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST,
    921     &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH,
    922     &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS,
    923     &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC,
    924     &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS,
    925     &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR,
     993#define OPCODE(x,_) &&L_OP_ ## x,
     994#include "mruby/ops.h"
     995#undef OPCODE
    926996  };
    927997#endif
     
    9341004  if (exc_catched) {
    9351005    exc_catched = FALSE;
     1006    mrb_gc_arena_restore(mrb, ai);
    9361007    if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK)
    9371008      goto L_BREAK;
     
    9401011  mrb->jmp = &c_jmp;
    9411012  mrb->c->ci->proc = proc;
    942   mrb->c->ci->nregs = irep->nregs;
    9431013
    9441014#define regs (mrb->c->stack)
    9451015  INIT_DISPATCH {
    946     CASE(OP_NOP) {
     1016    CASE(OP_NOP, Z) {
    9471017      /* do nothing */
    9481018      NEXT;
    9491019    }
    9501020
    951     CASE(OP_MOVE) {
    952       /* A B    R(A) := R(B) */
    953       int a = GETARG_A(i);
    954       int b = GETARG_B(i);
     1021    CASE(OP_MOVE, BB) {
    9551022      regs[a] = regs[b];
    9561023      NEXT;
    9571024    }
    9581025
    959     CASE(OP_LOADL) {
    960       /* A Bx   R(A) := Pool(Bx) */
    961       int a = GETARG_A(i);
    962       int bx = GETARG_Bx(i);
     1026    CASE(OP_LOADL, BB) {
    9631027#ifdef MRB_WORD_BOXING
    964       mrb_value val = pool[bx];
     1028      mrb_value val = pool[b];
     1029#ifndef MRB_WITHOUT_FLOAT
    9651030      if (mrb_float_p(val)) {
    9661031        val = mrb_float_value(mrb, mrb_float(val));
    9671032      }
     1033#endif
    9681034      regs[a] = val;
    9691035#else
    970       regs[a] = pool[bx];
    971 #endif
    972       NEXT;
    973     }
    974 
    975     CASE(OP_LOADI) {
    976       /* A sBx  R(A) := sBx */
    977       SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i));
    978       NEXT;
    979     }
    980 
    981     CASE(OP_LOADSYM) {
    982       /* A Bx   R(A) := Syms(Bx) */
    983       int a = GETARG_A(i);
    984       int bx = GETARG_Bx(i);
    985       SET_SYM_VALUE(regs[a], syms[bx]);
    986       NEXT;
    987     }
    988 
    989     CASE(OP_LOADSELF) {
    990       /* A      R(A) := self */
    991       int a = GETARG_A(i);
     1036      regs[a] = pool[b];
     1037#endif
     1038      NEXT;
     1039    }
     1040
     1041    CASE(OP_LOADI, BB) {
     1042      SET_INT_VALUE(regs[a], b);
     1043      NEXT;
     1044    }
     1045
     1046    CASE(OP_LOADINEG, BB) {
     1047      SET_INT_VALUE(regs[a], -b);
     1048      NEXT;
     1049    }
     1050
     1051    CASE(OP_LOADI__1,B) goto L_LOADI;
     1052    CASE(OP_LOADI_0,B) goto L_LOADI;
     1053    CASE(OP_LOADI_1,B) goto L_LOADI;
     1054    CASE(OP_LOADI_2,B) goto L_LOADI;
     1055    CASE(OP_LOADI_3,B) goto L_LOADI;
     1056    CASE(OP_LOADI_4,B) goto L_LOADI;
     1057    CASE(OP_LOADI_5,B) goto L_LOADI;
     1058    CASE(OP_LOADI_6,B) goto L_LOADI;
     1059    CASE(OP_LOADI_7, B) {
     1060    L_LOADI:
     1061      SET_INT_VALUE(regs[a], (mrb_int)insn - (mrb_int)OP_LOADI_0);
     1062      NEXT;
     1063    }
     1064
     1065    CASE(OP_LOADSYM, BB) {
     1066      SET_SYM_VALUE(regs[a], syms[b]);
     1067      NEXT;
     1068    }
     1069
     1070    CASE(OP_LOADNIL, B) {
     1071      SET_NIL_VALUE(regs[a]);
     1072      NEXT;
     1073    }
     1074
     1075    CASE(OP_LOADSELF, B) {
    9921076      regs[a] = regs[0];
    9931077      NEXT;
    9941078    }
    9951079
    996     CASE(OP_LOADT) {
    997       /* A      R(A) := true */
    998       int a = GETARG_A(i);
     1080    CASE(OP_LOADT, B) {
    9991081      SET_TRUE_VALUE(regs[a]);
    10001082      NEXT;
    10011083    }
    10021084
    1003     CASE(OP_LOADF) {
    1004       /* A      R(A) := false */
    1005       int a = GETARG_A(i);
     1085    CASE(OP_LOADF, B) {
    10061086      SET_FALSE_VALUE(regs[a]);
    10071087      NEXT;
    10081088    }
    10091089
    1010     CASE(OP_GETGLOBAL) {
    1011       /* A Bx   R(A) := getglobal(Syms(Bx)) */
    1012       int a = GETARG_A(i);
    1013       int bx = GETARG_Bx(i);
    1014       mrb_value val = mrb_gv_get(mrb, syms[bx]);
     1090    CASE(OP_GETGV, BB) {
     1091      mrb_value val = mrb_gv_get(mrb, syms[b]);
    10151092      regs[a] = val;
    10161093      NEXT;
    10171094    }
    10181095
    1019     CASE(OP_SETGLOBAL) {
    1020       /* A Bx   setglobal(Syms(Bx), R(A)) */
    1021       int a = GETARG_A(i);
    1022       int bx = GETARG_Bx(i);
    1023       mrb_gv_set(mrb, syms[bx], regs[a]);
    1024       NEXT;
    1025     }
    1026 
    1027     CASE(OP_GETSPECIAL) {
    1028       /* A Bx   R(A) := Special[Bx] */
    1029       int a = GETARG_A(i);
    1030       int bx = GETARG_Bx(i);
    1031       mrb_value val = mrb_vm_special_get(mrb, bx);
     1096    CASE(OP_SETGV, BB) {
     1097      mrb_gv_set(mrb, syms[b], regs[a]);
     1098      NEXT;
     1099    }
     1100
     1101    CASE(OP_GETSV, BB) {
     1102      mrb_value val = mrb_vm_special_get(mrb, b);
    10321103      regs[a] = val;
    10331104      NEXT;
    10341105    }
    10351106
    1036     CASE(OP_SETSPECIAL) {
    1037       /* A Bx   Special[Bx] := R(A) */
    1038       int a = GETARG_A(i);
    1039       int bx = GETARG_Bx(i);
    1040       mrb_vm_special_set(mrb, bx, regs[a]);
    1041       NEXT;
    1042     }
    1043 
    1044     CASE(OP_GETIV) {
    1045       /* A Bx   R(A) := ivget(Bx) */
    1046       int a = GETARG_A(i);
    1047       int bx = GETARG_Bx(i);
    1048       mrb_value val = mrb_vm_iv_get(mrb, syms[bx]);
    1049       regs[a] = val;
    1050       NEXT;
    1051     }
    1052 
    1053     CASE(OP_SETIV) {
    1054       /* A Bx   ivset(Syms(Bx),R(A)) */
    1055       int a = GETARG_A(i);
    1056       int bx = GETARG_Bx(i);
    1057       mrb_vm_iv_set(mrb, syms[bx], regs[a]);
    1058       NEXT;
    1059     }
    1060 
    1061     CASE(OP_GETCV) {
    1062       /* A Bx   R(A) := cvget(Syms(Bx)) */
    1063       int a = GETARG_A(i);
    1064       int bx = GETARG_Bx(i);
     1107    CASE(OP_SETSV, BB) {
     1108      mrb_vm_special_set(mrb, b, regs[a]);
     1109      NEXT;
     1110    }
     1111
     1112    CASE(OP_GETIV, BB) {
     1113      regs[a] = mrb_iv_get(mrb, regs[0], syms[b]);
     1114      NEXT;
     1115    }
     1116
     1117    CASE(OP_SETIV, BB) {
     1118      mrb_iv_set(mrb, regs[0], syms[b], regs[a]);
     1119      NEXT;
     1120    }
     1121
     1122    CASE(OP_GETCV, BB) {
    10651123      mrb_value val;
    1066       ERR_PC_SET(mrb, pc);
    1067       val = mrb_vm_cv_get(mrb, syms[bx]);
     1124      ERR_PC_SET(mrb);
     1125      val = mrb_vm_cv_get(mrb, syms[b]);
    10681126      ERR_PC_CLR(mrb);
    10691127      regs[a] = val;
     
    10711129    }
    10721130
    1073     CASE(OP_SETCV) {
    1074       /* A Bx   cvset(Syms(Bx),R(A)) */
    1075       int a = GETARG_A(i);
    1076       int bx = GETARG_Bx(i);
    1077       mrb_vm_cv_set(mrb, syms[bx], regs[a]);
    1078       NEXT;
    1079     }
    1080 
    1081     CASE(OP_GETCONST) {
    1082       /* A Bx    R(A) := constget(Syms(Bx)) */
     1131    CASE(OP_SETCV, BB) {
     1132      mrb_vm_cv_set(mrb, syms[b], regs[a]);
     1133      NEXT;
     1134    }
     1135
     1136    CASE(OP_GETCONST, BB) {
    10831137      mrb_value val;
    1084       int a = GETARG_A(i);
    1085       int bx = GETARG_Bx(i);
    1086       mrb_sym sym = syms[bx];
    1087 
    1088       ERR_PC_SET(mrb, pc);
     1138      mrb_sym sym = syms[b];
     1139
     1140      ERR_PC_SET(mrb);
    10891141      val = mrb_vm_const_get(mrb, sym);
    10901142      ERR_PC_CLR(mrb);
     
    10931145    }
    10941146
    1095     CASE(OP_SETCONST) {
    1096       /* A Bx   constset(Syms(Bx),R(A)) */
    1097       int a = GETARG_A(i);
    1098       int bx = GETARG_Bx(i);
    1099       mrb_vm_const_set(mrb, syms[bx], regs[a]);
    1100       NEXT;
    1101     }
    1102 
    1103     CASE(OP_GETMCNST) {
    1104       /* A Bx   R(A) := R(A)::Syms(Bx) */
     1147    CASE(OP_SETCONST, BB) {
     1148      mrb_vm_const_set(mrb, syms[b], regs[a]);
     1149      NEXT;
     1150    }
     1151
     1152    CASE(OP_GETMCNST, BB) {
    11051153      mrb_value val;
    1106       int a = GETARG_A(i);
    1107       int bx = GETARG_Bx(i);
    1108 
    1109       ERR_PC_SET(mrb, pc);
    1110       val = mrb_const_get(mrb, regs[a], syms[bx]);
     1154
     1155      ERR_PC_SET(mrb);
     1156      val = mrb_const_get(mrb, regs[a], syms[b]);
    11111157      ERR_PC_CLR(mrb);
    11121158      regs[a] = val;
     
    11141160    }
    11151161
    1116     CASE(OP_SETMCNST) {
    1117       /* A Bx    R(A+1)::Syms(Bx) := R(A) */
    1118       int a = GETARG_A(i);
    1119       int bx = GETARG_Bx(i);
    1120       mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]);
    1121       NEXT;
    1122     }
    1123 
    1124     CASE(OP_GETUPVAR) {
    1125       /* A B C  R(A) := uvget(B,C) */
    1126       int a = GETARG_A(i);
    1127       int b = GETARG_B(i);
    1128       int c = GETARG_C(i);
     1162    CASE(OP_SETMCNST, BB) {
     1163      mrb_const_set(mrb, regs[a+1], syms[b], regs[a]);
     1164      NEXT;
     1165    }
     1166
     1167    CASE(OP_GETUPVAR, BBB) {
    11291168      mrb_value *regs_a = regs + a;
    11301169      struct REnv *e = uvenv(mrb, c);
    11311170
    1132       if (!e) {
     1171      if (e && b < MRB_ENV_STACK_LEN(e)) {
     1172        *regs_a = e->stack[b];
     1173      }
     1174      else {
    11331175        *regs_a = mrb_nil_value();
    11341176      }
    1135       else {
    1136         *regs_a = e->stack[b];
    1137       }
    1138       NEXT;
    1139     }
    1140 
    1141     CASE(OP_SETUPVAR) {
    1142       /* A B C  uvset(B,C,R(A)) */
    1143       int a = GETARG_A(i);
    1144       int b = GETARG_B(i);
    1145       int c = GETARG_C(i);
    1146 
     1177      NEXT;
     1178    }
     1179
     1180    CASE(OP_SETUPVAR, BBB) {
    11471181      struct REnv *e = uvenv(mrb, c);
    11481182
     
    11581192    }
    11591193
    1160     CASE(OP_JMP) {
    1161       /* sBx    pc+=sBx */
    1162       int sbx = GETARG_sBx(i);
    1163       pc += sbx;
     1194    CASE(OP_JMP, S) {
     1195      pc = irep->iseq+a;
    11641196      JUMP;
    11651197    }
    1166 
    1167     CASE(OP_JMPIF) {
    1168       /* A sBx  if R(A) pc+=sBx */
    1169       int a = GETARG_A(i);
    1170       int sbx = GETARG_sBx(i);
     1198    CASE(OP_JMPIF, BS) {
    11711199      if (mrb_test(regs[a])) {
    1172         pc += sbx;
     1200        pc = irep->iseq+b;
    11731201        JUMP;
    11741202      }
    11751203      NEXT;
    11761204    }
    1177 
    1178     CASE(OP_JMPNOT) {
    1179       /* A sBx  if !R(A) pc+=sBx */
    1180       int a = GETARG_A(i);
    1181       int sbx = GETARG_sBx(i);
     1205    CASE(OP_JMPNOT, BS) {
    11821206      if (!mrb_test(regs[a])) {
    1183         pc += sbx;
     1207        pc = irep->iseq+b;
    11841208        JUMP;
    11851209      }
    11861210      NEXT;
    11871211    }
    1188 
    1189     CASE(OP_ONERR) {
    1190       /* sBx    pc+=sBx on exception */
    1191       int sbx = GETARG_sBx(i);
     1212    CASE(OP_JMPNIL, BS) {
     1213      if (mrb_nil_p(regs[a])) {
     1214        pc = irep->iseq+b;
     1215        JUMP;
     1216      }
     1217      NEXT;
     1218    }
     1219
     1220    CASE(OP_ONERR, S) {
     1221      /* check rescue stack */
     1222      if (mrb->c->ci->ridx == UINT16_MAX-1) {
     1223        mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested rescues");
     1224        mrb_exc_set(mrb, exc);
     1225        goto L_RAISE;
     1226      }
     1227      /* expand rescue stack */
    11921228      if (mrb->c->rsize <= mrb->c->ci->ridx) {
    11931229        if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE;
    1194         else mrb->c->rsize *= 2;
    1195         mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize);
    1196       }
    1197       mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx;
    1198       NEXT;
    1199     }
    1200 
    1201     CASE(OP_RESCUE) {
    1202       /* A B    R(A) := exc; clear(exc); R(B) := matched (bool) */
    1203       int a = GETARG_A(i);
    1204       int b = GETARG_B(i);
    1205       int c = GETARG_C(i);
    1206       mrb_value exc;
    1207 
    1208       if (c == 0) {
    1209         exc = mrb_obj_value(mrb->exc);
    1210         mrb->exc = 0;
    1211       }
    1212       else {           /* continued; exc taken from R(A) */
    1213         exc = regs[a];
    1214       }
    1215       if (b != 0) {
    1216         mrb_value e = regs[b];
    1217         struct RClass *ec;
    1218 
    1219         switch (mrb_type(e)) {
    1220         case MRB_TT_CLASS:
    1221         case MRB_TT_MODULE:
    1222           break;
    1223         default:
    1224           {
    1225             mrb_value exc;
    1226 
    1227             exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
    1228                   "class or module required for rescue clause");
    1229             mrb_exc_set(mrb, exc);
    1230             goto L_RAISE;
    1231           }
    1232         }
    1233         ec = mrb_class_ptr(e);
    1234         regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec));
    1235       }
    1236       if (a != 0 && c == 0) {
    1237         regs[a] = exc;
    1238       }
    1239       NEXT;
    1240     }
    1241 
    1242     CASE(OP_POPERR) {
    1243       /* A      A.times{rescue_pop()} */
    1244       int a = GETARG_A(i);
    1245 
    1246       while (a--) {
    1247         mrb->c->ci->ridx--;
    1248       }
    1249       NEXT;
    1250     }
    1251 
    1252     CASE(OP_RAISE) {
    1253       /* A      raise(R(A)) */
    1254       int a = GETARG_A(i);
    1255 
     1230        else {
     1231          mrb->c->rsize *= 2;
     1232          if (mrb->c->rsize <= mrb->c->ci->ridx) {
     1233            mrb->c->rsize = UINT16_MAX;
     1234          }
     1235        }
     1236        mrb->c->rescue = (uint16_t*)mrb_realloc(mrb, mrb->c->rescue, sizeof(uint16_t)*mrb->c->rsize);
     1237      }
     1238      /* push rescue stack */
     1239      mrb->c->rescue[mrb->c->ci->ridx++] = a;
     1240      NEXT;
     1241    }
     1242
     1243    CASE(OP_EXCEPT, B) {
     1244      mrb_value exc = mrb_obj_value(mrb->exc);
     1245      mrb->exc = 0;
     1246      regs[a] = exc;
     1247      NEXT;
     1248    }
     1249    CASE(OP_RESCUE, BB) {
     1250      mrb_value exc = regs[a];  /* exc on stack */
     1251      mrb_value e = regs[b];
     1252      struct RClass *ec;
     1253
     1254      switch (mrb_type(e)) {
     1255      case MRB_TT_CLASS:
     1256      case MRB_TT_MODULE:
     1257        break;
     1258      default:
     1259        {
     1260          mrb_value exc;
     1261
     1262          exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
     1263                                    "class or module required for rescue clause");
     1264          mrb_exc_set(mrb, exc);
     1265          goto L_RAISE;
     1266        }
     1267      }
     1268      ec = mrb_class_ptr(e);
     1269      regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec));
     1270      NEXT;
     1271    }
     1272
     1273    CASE(OP_POPERR, B) {
     1274      mrb->c->ci->ridx -= a;
     1275      NEXT;
     1276    }
     1277
     1278    CASE(OP_RAISE, B) {
    12561279      mrb_exc_set(mrb, regs[a]);
    12571280      goto L_RAISE;
    12581281    }
    12591282
    1260     CASE(OP_EPUSH) {
    1261       /* Bx     ensure_push(SEQ[Bx]) */
    1262       int bx = GETARG_Bx(i);
     1283    CASE(OP_EPUSH, B) {
    12631284      struct RProc *p;
    12641285
    1265       p = mrb_closure_new(mrb, irep->reps[bx]);
    1266       /* push ensure_stack */
     1286      p = mrb_closure_new(mrb, irep->reps[a]);
     1287      /* check ensure stack */
     1288      if (mrb->c->eidx == UINT16_MAX-1) {
     1289        mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested ensures");
     1290        mrb_exc_set(mrb, exc);
     1291        goto L_RAISE;
     1292      }
     1293      /* expand ensure stack */
    12671294      if (mrb->c->esize <= mrb->c->eidx+1) {
    12681295        if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE;
    1269         else mrb->c->esize *= 2;
    1270         mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize);
    1271       }
     1296        else {
     1297          mrb->c->esize *= 2;
     1298          if (mrb->c->esize <= mrb->c->eidx) {
     1299            mrb->c->esize = UINT16_MAX;
     1300          }
     1301        }
     1302        mrb->c->ensure = (struct RProc**)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*)*mrb->c->esize);
     1303      }
     1304      /* push ensure stack */
    12721305      mrb->c->ensure[mrb->c->eidx++] = p;
    12731306      mrb->c->ensure[mrb->c->eidx] = NULL;
    1274       ARENA_RESTORE(mrb, ai);
    1275       NEXT;
    1276     }
    1277 
    1278     CASE(OP_EPOP) {
    1279       /* A      A.times{ensure_pop().call} */
    1280       int a = GETARG_A(i);
     1307      mrb_gc_arena_restore(mrb, ai);
     1308      NEXT;
     1309    }
     1310
     1311    CASE(OP_EPOP, B) {
    12811312      mrb_callinfo *ci = mrb->c->ci;
    1282       int n, epos = ci->epos;
    1283 
    1284       for (n=0; n<a && mrb->c->eidx > epos; n++) {
    1285         ecall(mrb, --mrb->c->eidx);
    1286         ARENA_RESTORE(mrb, ai);
    1287       }
    1288       NEXT;
    1289     }
    1290 
    1291     CASE(OP_LOADNIL) {
    1292       /* A     R(A) := nil */
    1293       int a = GETARG_A(i);
    1294 
    1295       SET_NIL_VALUE(regs[a]);
    1296       NEXT;
    1297     }
    1298 
    1299     CASE(OP_SENDB) {
    1300       /* A B C  R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/
    1301       /* fall through */
     1313      unsigned int n, epos = ci->epos;
     1314      mrb_value self = regs[0];
     1315      struct RClass *target_class = ci->target_class;
     1316
     1317      if (mrb->c->eidx <= epos) {
     1318        NEXT;
     1319      }
     1320
     1321      if (a > (int)mrb->c->eidx - epos)
     1322        a = mrb->c->eidx - epos;
     1323      for (n=0; n<a; n++) {
     1324        int nregs = irep->nregs;
     1325
     1326        proc = mrb->c->ensure[epos+n];
     1327        mrb->c->ensure[epos+n] = NULL;
     1328        if (proc == NULL) continue;
     1329        irep = proc->body.irep;
     1330        ci = cipush(mrb);
     1331        ci->mid = ci[-1].mid;
     1332        ci->argc = 0;
     1333        ci->proc = proc;
     1334        ci->stackent = mrb->c->stack;
     1335        ci->target_class = target_class;
     1336        ci->pc = pc;
     1337        ci->acc = nregs;
     1338        mrb->c->stack += ci->acc;
     1339        mrb_stack_extend(mrb, irep->nregs);
     1340        regs[0] = self;
     1341        pc = irep->iseq;
     1342      }
     1343      pool = irep->pool;
     1344      syms = irep->syms;
     1345      mrb->c->eidx = epos;
     1346      JUMP;
     1347    }
     1348
     1349    CASE(OP_SENDV, BB) {
     1350      c = CALL_MAXARGS;
     1351      goto L_SEND;
    13021352    };
    13031353
    1304   L_SEND:
    1305     CASE(OP_SEND) {
    1306       /* A B C  R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */
    1307       int a = GETARG_A(i);
    1308       int n = GETARG_C(i);
    1309       struct RProc *m;
    1310       struct RClass *c;
     1354    CASE(OP_SENDVB, BB) {
     1355      c = CALL_MAXARGS;
     1356      goto L_SENDB;
     1357    };
     1358
     1359    CASE(OP_SEND, BBB)
     1360    L_SEND:
     1361    {
     1362      /* push nil after arguments */
     1363      int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1;
     1364      SET_NIL_VALUE(regs[bidx]);
     1365      goto L_SENDB;
     1366    };
     1367    L_SEND_SYM:
     1368    {
     1369      /* push nil after arguments */
     1370      int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1;
     1371      SET_NIL_VALUE(regs[bidx]);
     1372      goto L_SENDB_SYM;
     1373    };
     1374
     1375    CASE(OP_SENDB, BBB)
     1376    L_SENDB:
     1377    mid = syms[b];
     1378    L_SENDB_SYM:
     1379    {
     1380      int argc = (c == CALL_MAXARGS) ? -1 : c;
     1381      int bidx = (argc < 0) ? a+2 : a+c+1;
     1382      mrb_method_t m;
     1383      struct RClass *cls;
    13111384      mrb_callinfo *ci = mrb->c->ci;
    1312       mrb_value recv, result;
    1313       mrb_sym mid = syms[GETARG_B(i)];
    1314       int bidx;
    1315       mrb_value blk;
     1385      mrb_value recv, blk;
     1386
     1387      mrb_assert(bidx < irep->nregs);
    13161388
    13171389      recv = regs[a];
    1318       if (n == CALL_MAXARGS) {
    1319         bidx = a+2;
    1320       }
    1321       else {
    1322         bidx = a+n+1;
    1323       }
    1324       if (GET_OPCODE(i) != OP_SENDB) {
    1325         if (bidx >= ci->nregs) {
    1326           stack_extend(mrb, bidx+1);
    1327           ci->nregs = bidx+1;
    1328         }
    1329         SET_NIL_VALUE(regs[bidx]);
    1330         blk = mrb_nil_value();
    1331       }
    1332       else {
    1333         blk = regs[bidx];
    1334         if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
    1335           if (bidx >= ci->nregs) {
    1336             stack_extend(mrb, bidx+1);
    1337             ci->nregs = bidx+1;
    1338           }
    1339           result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
    1340           blk = regs[bidx] = result;
    1341         }
    1342       }
    1343       c = mrb_class(mrb, recv);
    1344       m = mrb_method_search_vm(mrb, &c, mid);
    1345       if (!m) {
    1346         mrb_value sym = mrb_symbol_value(mid);
     1390      blk = regs[bidx];
     1391      if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
     1392        blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
     1393        /* The stack might have been reallocated during mrb_convert_type(),
     1394           see #3622 */
     1395        regs[bidx] = blk;
     1396      }
     1397      cls = mrb_class(mrb, recv);
     1398      m = mrb_method_search_vm(mrb, &cls, mid);
     1399      if (MRB_METHOD_UNDEF_P(m)) {
    13471400        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    1348 
    1349         m = mrb_method_search_vm(mrb, &c, missing);
    1350         if (!m) {
    1351           mrb_value args;
    1352 
    1353           if (n == CALL_MAXARGS) {
    1354             args = regs[a+1];
    1355           }
    1356           else {
    1357             args = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1358           }
    1359           ERR_PC_SET(mrb, pc);
     1401        m = mrb_method_search_vm(mrb, &cls, missing);
     1402        if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) {
     1403          mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1);
     1404          ERR_PC_SET(mrb);
    13601405          mrb_method_missing(mrb, mid, recv, args);
    13611406        }
     1407        if (argc >= 0) {
     1408          if (a+2 >= irep->nregs) {
     1409            mrb_stack_extend(mrb, a+3);
     1410          }
     1411          regs[a+1] = mrb_ary_new_from_values(mrb, c, regs+a+1);
     1412          regs[a+2] = blk;
     1413          argc = -1;
     1414        }
     1415        mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid));
    13621416        mid = missing;
    1363         if (n != CALL_MAXARGS) {
    1364           if (a+2 >= irep->nregs) {
    1365             stack_extend(mrb, a+3);
    1366           }
    1367           regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1368           regs[a+2] = blk;
    1369           n = CALL_MAXARGS;
    1370         }
    1371         mrb_ary_unshift(mrb, regs[a+1], sym);
    13721417      }
    13731418
     
    13751420      ci = cipush(mrb);
    13761421      ci->mid = mid;
    1377       ci->proc = m;
    13781422      ci->stackent = mrb->c->stack;
    1379       ci->target_class = c;
    1380 
    1381       ci->pc = pc + 1;
     1423      ci->target_class = cls;
     1424      ci->argc = argc;
     1425
     1426      ci->pc = pc;
    13821427      ci->acc = a;
    13831428
     
    13851430      mrb->c->stack += a;
    13861431
    1387       if (MRB_PROC_CFUNC_P(m)) {
    1388         if (n == CALL_MAXARGS) {
    1389           ci->argc = -1;
    1390           ci->nregs = 3;
     1432      if (MRB_METHOD_CFUNC_P(m)) {
     1433        if (MRB_METHOD_PROC_P(m)) {
     1434          struct RProc *p = MRB_METHOD_PROC(m);
     1435
     1436          ci->proc = p;
     1437          recv = p->body.func(mrb, recv);
     1438        }
     1439        else if (MRB_METHOD_NOARG_P(m) &&
     1440                 (argc > 0 || (argc == -1 && RARRAY_LEN(regs[1]) != 0))) {
     1441          argnum_error(mrb, 0);
     1442          goto L_RAISE;
    13911443        }
    13921444        else {
    1393           ci->argc = n;
    1394           ci->nregs = n + 2;
    1395         }
    1396         result = m->body.func(mrb, recv);
     1445          recv = MRB_METHOD_FUNC(m)(mrb, recv);
     1446        }
    13971447        mrb_gc_arena_restore(mrb, ai);
     1448        mrb_gc_arena_shrink(mrb, ai);
    13981449        if (mrb->exc) goto L_RAISE;
    13991450        ci = mrb->c->ci;
    1400         if (GET_OPCODE(i) == OP_SENDB) {
    1401           if (mrb_type(blk) == MRB_TT_PROC) {
    1402             struct RProc *p = mrb_proc_ptr(blk);
    1403 
    1404             if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) {
    1405               p->flags |= MRB_PROC_ORPHAN;
    1406             }
     1451        if (mrb_proc_p(blk)) {
     1452          struct RProc *p = mrb_proc_ptr(blk);
     1453          if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) {
     1454            p->flags |= MRB_PROC_ORPHAN;
    14071455          }
    14081456        }
     
    14101458          if (ci->acc == CI_ACC_RESUMED) {
    14111459            mrb->jmp = prev_jmp;
    1412             return result;
     1460            return recv;
    14131461          }
    14141462          else {
     
    14201468          }
    14211469        }
    1422         mrb->c->stack[0] = result;
     1470        mrb->c->stack[0] = recv;
    14231471        /* pop stackpos */
    14241472        mrb->c->stack = ci->stackent;
     
    14291477      else {
    14301478        /* setup environment for calling method */
    1431         proc = mrb->c->ci->proc = m;
    1432         irep = m->body.irep;
     1479        proc = ci->proc = MRB_METHOD_PROC(m);
     1480        irep = proc->body.irep;
    14331481        pool = irep->pool;
    14341482        syms = irep->syms;
    1435         ci->nregs = irep->nregs;
    1436         if (n == CALL_MAXARGS) {
    1437           ci->argc = -1;
    1438           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    1439         }
    1440         else {
    1441           ci->argc = n;
    1442           stack_extend(mrb, irep->nregs);
    1443         }
     1483        mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs);
    14441484        pc = irep->iseq;
    14451485        JUMP;
     
    14471487    }
    14481488
    1449     CASE(OP_FSEND) {
    1450       /* A B C  R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */
    1451       /* not implemented yet */
    1452       NEXT;
    1453     }
    1454 
    1455     CASE(OP_CALL) {
    1456       /* A      R(A) := self.call(frame.argc, frame.argv) */
     1489    CASE(OP_CALL, Z) {
    14571490      mrb_callinfo *ci;
    14581491      mrb_value recv = mrb->c->stack[0];
     
    14611494      /* replace callinfo */
    14621495      ci = mrb->c->ci;
    1463       ci->target_class = m->target_class;
     1496      ci->target_class = MRB_PROC_TARGET_CLASS(m);
    14641497      ci->proc = m;
    1465       if (m->env) {
    1466         mrb_sym mid;
    1467 
    1468         if (MRB_ENV_STACK_SHARED_P(m->env)) {
    1469           mid = m->env->cxt.c->cibase[m->env->cioff].mid;
    1470         }
    1471         else {
    1472           mid = m->env->cxt.mid;
    1473         }
    1474         if (mid) ci->mid = mid;
    1475         if (!m->env->stack) {
    1476           m->env->stack = mrb->c->stack;
     1498      if (MRB_PROC_ENV_P(m)) {
     1499        struct REnv *e = MRB_PROC_ENV(m);
     1500
     1501        ci->mid = e->mid;
     1502        if (!e->stack) {
     1503          e->stack = mrb->c->stack;
    14771504        }
    14781505      }
     
    14801507      /* prepare stack */
    14811508      if (MRB_PROC_CFUNC_P(m)) {
    1482         recv = m->body.func(mrb, recv);
     1509        recv = MRB_PROC_CFUNC(m)(mrb, recv);
    14831510        mrb_gc_arena_restore(mrb, ai);
     1511        mrb_gc_arena_shrink(mrb, ai);
    14841512        if (mrb->exc) goto L_RAISE;
    14851513        /* pop stackpos */
     
    15001528        if (!irep) {
    15011529          mrb->c->stack[0] = mrb_nil_value();
    1502           goto L_RETURN;
     1530          a = 0;
     1531          c = OP_R_NORMAL;
     1532          goto L_OP_RETURN_BODY;
    15031533        }
    15041534        pool = irep->pool;
    15051535        syms = irep->syms;
    1506         ci->nregs = irep->nregs;
    1507         stack_extend(mrb, irep->nregs);
     1536        mrb_stack_extend(mrb, irep->nregs);
    15081537        if (ci->argc < 0) {
    15091538          if (irep->nregs > 3) {
     
    15141543          stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2);
    15151544        }
    1516         if (m->env) {
    1517           regs[0] = m->env->stack[0];
     1545        if (MRB_PROC_ENV_P(m)) {
     1546          regs[0] = MRB_PROC_ENV(m)->stack[0];
    15181547        }
    15191548        pc = irep->iseq;
     
    15221551    }
    15231552
    1524     CASE(OP_SUPER) {
    1525       /* A C  R(A) := super(R(A+1),... ,R(A+C+1)) */
    1526       mrb_value recv;
     1553    CASE(OP_SUPER, BB) {
     1554      int argc = (b == CALL_MAXARGS) ? -1 : b;
     1555      int bidx = (argc < 0) ? a+2 : a+b+1;
     1556      mrb_method_t m;
     1557      struct RClass *cls;
    15271558      mrb_callinfo *ci = mrb->c->ci;
    1528       struct RProc *m;
    1529       struct RClass *c;
     1559      mrb_value recv, blk;
     1560      struct RProc *p = ci->proc;
    15301561      mrb_sym mid = ci->mid;
    1531       int a = GETARG_A(i);
    1532       int n = GETARG_C(i);
    1533       mrb_value blk;
    1534       int bidx;
    1535 
    1536       if (mid == 0 || !ci->target_class) {
    1537         mrb_value exc;
    1538 
    1539         exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
     1562      struct RClass* target_class = MRB_PROC_TARGET_CLASS(p);
     1563
     1564      if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */
     1565        mid = p->e.env->mid;    /* restore old mid */
     1566      }
     1567      mrb_assert(bidx < irep->nregs);
     1568
     1569      if (mid == 0 || !target_class) {
     1570        mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
    15401571        mrb_exc_set(mrb, exc);
    15411572        goto L_RAISE;
    15421573      }
     1574      if (target_class->tt == MRB_TT_MODULE) {
     1575        target_class = ci->target_class;
     1576        if (target_class->tt != MRB_TT_ICLASS) {
     1577          mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]");
     1578          mrb_exc_set(mrb, exc);
     1579          goto L_RAISE;
     1580        }
     1581      }
    15431582      recv = regs[0];
    1544       c = mrb->c->ci->target_class->super;
    1545       m = mrb_method_search_vm(mrb, &c, mid);
    1546       if (!m) {
     1583      if (!mrb_obj_is_kind_of(mrb, recv, target_class)) {
     1584        mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
     1585                                            "self has wrong type to call super in this context");
     1586        mrb_exc_set(mrb, exc);
     1587        goto L_RAISE;
     1588      }
     1589      blk = regs[bidx];
     1590      if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
     1591        blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
     1592        /* The stack or ci stack might have been reallocated during
     1593           mrb_convert_type(), see #3622 and #3784 */
     1594        regs[bidx] = blk;
     1595        ci = mrb->c->ci;
     1596      }
     1597      cls = target_class->super;
     1598      m = mrb_method_search_vm(mrb, &cls, mid);
     1599      if (MRB_METHOD_UNDEF_P(m)) {
    15471600        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    1548         m = mrb_method_search_vm(mrb, &c, missing);
    1549         if (!m) {
    1550           mrb_value args;
    1551 
    1552           if (n == CALL_MAXARGS) {
    1553             args = regs[a+1];
    1554           }
    1555           else {
    1556             args = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1557           }
    1558           ERR_PC_SET(mrb, pc);
     1601
     1602        if (mid != missing) {
     1603          cls = mrb_class(mrb, recv);
     1604        }
     1605        m = mrb_method_search_vm(mrb, &cls, missing);
     1606        if (MRB_METHOD_UNDEF_P(m)) {
     1607          mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1);
     1608          ERR_PC_SET(mrb);
    15591609          mrb_method_missing(mrb, mid, recv, args);
    15601610        }
    15611611        mid = missing;
    1562         if (n == CALL_MAXARGS-1) {
    1563           regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1564           n++;
    1565         }
    1566         if (n == CALL_MAXARGS) {
    1567           mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
    1568         }
    1569         else {
    1570           value_move(regs+a+2, regs+a+1, ++n);
    1571           SET_SYM_VALUE(regs[a+1], ci->mid);
    1572         }
    1573       }
    1574 
    1575       if (n == CALL_MAXARGS) {
    1576         bidx = a+2;
    1577       }
    1578       else {
    1579         bidx = a+n+1;
    1580       }
    1581       blk = regs[bidx];
    1582       if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
    1583         mrb_value result;
    1584 
    1585         if (bidx >= ci->nregs) {
    1586           stack_extend(mrb, bidx+1);
    1587           ci->nregs = bidx+1;
    1588         }
    1589         result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
    1590         regs[bidx] = result;
     1612        if (argc >= 0) {
     1613          if (a+2 >= irep->nregs) {
     1614            mrb_stack_extend(mrb, a+3);
     1615          }
     1616          regs[a+1] = mrb_ary_new_from_values(mrb, b, regs+a+1);
     1617          regs[a+2] = blk;
     1618          argc = -1;
     1619        }
     1620        mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
    15911621      }
    15921622
     
    15941624      ci = cipush(mrb);
    15951625      ci->mid = mid;
    1596       ci->proc = m;
    15971626      ci->stackent = mrb->c->stack;
    1598       ci->target_class = c;
    1599       ci->pc = pc + 1;
    1600       if (n == CALL_MAXARGS) {
    1601         ci->argc = -1;
    1602       }
    1603       else {
    1604         ci->argc = n;
    1605       }
     1627      ci->target_class = cls;
     1628      ci->pc = pc;
     1629      ci->argc = argc;
    16061630
    16071631      /* prepare stack */
     
    16091633      mrb->c->stack[0] = recv;
    16101634
    1611       if (MRB_PROC_CFUNC_P(m)) {
     1635      if (MRB_METHOD_CFUNC_P(m)) {
    16121636        mrb_value v;
    16131637
    1614         if (n == CALL_MAXARGS) {
    1615           ci->nregs = 3;
    1616         }
    1617         else {
    1618           ci->nregs = n + 2;
    1619         }
    1620         v = m->body.func(mrb, recv);
     1638        if (MRB_METHOD_PROC_P(m)) {
     1639          ci->proc = MRB_METHOD_PROC(m);
     1640        }
     1641        v = MRB_METHOD_CFUNC(m)(mrb, recv);
    16211642        mrb_gc_arena_restore(mrb, ai);
    16221643        if (mrb->exc) goto L_RAISE;
     
    16471668
    16481669        /* setup environment for calling method */
    1649         ci->proc = m;
    1650         irep = m->body.irep;
     1670        proc = ci->proc = MRB_METHOD_PROC(m);
     1671        irep = proc->body.irep;
    16511672        pool = irep->pool;
    16521673        syms = irep->syms;
    1653         ci->nregs = irep->nregs;
    1654         if (n == CALL_MAXARGS) {
    1655           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    1656         }
    1657         else {
    1658           stack_extend(mrb, irep->nregs);
    1659         }
     1674        mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs);
    16601675        pc = irep->iseq;
    16611676        JUMP;
     
    16631678    }
    16641679
    1665     CASE(OP_ARGARY) {
    1666       /* A Bx   R(A) := argument array (16=6:1:5:4) */
    1667       int a = GETARG_A(i);
    1668       int bx = GETARG_Bx(i);
    1669       int m1 = (bx>>10)&0x3f;
    1670       int r  = (bx>>9)&0x1;
    1671       int m2 = (bx>>4)&0x1f;
    1672       int lv = (bx>>0)&0xf;
     1680    CASE(OP_ARGARY, BS) {
     1681      int m1 = (b>>11)&0x3f;
     1682      int r  = (b>>10)&0x1;
     1683      int m2 = (b>>5)&0x1f;
     1684      int kd = (b>>4)&0x1;
     1685      int lv = (b>>0)&0xf;
    16731686      mrb_value *stack;
    16741687
     
    16851698        struct REnv *e = uvenv(mrb, lv-1);
    16861699        if (!e) goto L_NOSUPER;
     1700        if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+kd+1)
     1701          goto L_NOSUPER;
    16871702        stack = e->stack + 1;
    16881703      }
    16891704      if (r == 0) {
    1690         regs[a] = mrb_ary_new_from_values(mrb, m1+m2, stack);
     1705        regs[a] = mrb_ary_new_from_values(mrb, m1+m2+kd, stack);
    16911706      }
    16921707      else {
     
    16981713          struct RArray *ary = mrb_ary_ptr(stack[m1]);
    16991714
    1700           pp = ary->ptr;
    1701           len = ary->len;
    1702         }
    1703         regs[a] = mrb_ary_new_capa(mrb, m1+len+m2);
     1715          pp = ARY_PTR(ary);
     1716          len = (int)ARY_LEN(ary);
     1717        }
     1718        regs[a] = mrb_ary_new_capa(mrb, m1+len+m2+kd);
    17041719        rest = mrb_ary_ptr(regs[a]);
    17051720        if (m1 > 0) {
    1706           stack_copy(rest->ptr, stack, m1);
     1721          stack_copy(ARY_PTR(rest), stack, m1);
    17071722        }
    17081723        if (len > 0) {
    1709           stack_copy(rest->ptr+m1, pp, len);
     1724          stack_copy(ARY_PTR(rest)+m1, pp, len);
    17101725        }
    17111726        if (m2 > 0) {
    1712           stack_copy(rest->ptr+m1+len, stack+m1+1, m2);
    1713         }
    1714         rest->len = m1+len+m2;
     1727          stack_copy(ARY_PTR(rest)+m1+len, stack+m1+1, m2);
     1728        }
     1729        if (kd) {
     1730          stack_copy(ARY_PTR(rest)+m1+len+m2, stack+m1+m2+1, kd);
     1731        }
     1732        ARY_SET_LEN(rest, m1+len+m2+kd);
    17151733      }
    17161734      regs[a+1] = stack[m1+r+m2];
    1717       ARENA_RESTORE(mrb, ai);
    1718       NEXT;
    1719     }
    1720 
    1721     CASE(OP_ENTER) {
    1722       /* Ax             arg setup according to flags (23=5:5:1:5:5:1:1) */
    1723       /* number of optional arguments times OP_JMP should follow */
    1724       mrb_aspec ax = GETARG_Ax(i);
    1725       int m1 = MRB_ASPEC_REQ(ax);
    1726       int o  = MRB_ASPEC_OPT(ax);
    1727       int r  = MRB_ASPEC_REST(ax);
    1728       int m2 = MRB_ASPEC_POST(ax);
     1735      mrb_gc_arena_restore(mrb, ai);
     1736      NEXT;
     1737    }
     1738
     1739    CASE(OP_ENTER, W) {
     1740      int m1 = MRB_ASPEC_REQ(a);
     1741      int o  = MRB_ASPEC_OPT(a);
     1742      int r  = MRB_ASPEC_REST(a);
     1743      int m2 = MRB_ASPEC_POST(a);
     1744      int kd = (MRB_ASPEC_KEY(a) > 0 || MRB_ASPEC_KDICT(a))? 1 : 0;
    17291745      /* unused
    1730       int k  = MRB_ASPEC_KEY(ax);
    1731       int kd = MRB_ASPEC_KDICT(ax);
    1732       int b  = MRB_ASPEC_BLOCK(ax);
     1746      int b  = MRB_ASPEC_BLOCK(a);
    17331747      */
    17341748      int argc = mrb->c->ci->argc;
    17351749      mrb_value *argv = regs+1;
    1736       mrb_value *argv0 = argv;
    1737       int len = m1 + o + r + m2;
     1750      mrb_value * const argv0 = argv;
     1751      int const len = m1 + o + r + m2;
     1752      int const blk_pos = len + kd + 1;
    17381753      mrb_value *blk = &argv[argc < 0 ? 1 : argc];
    1739 
     1754      mrb_value kdict;
     1755      int kargs = kd;
     1756
     1757      /* arguments is passed with Array */
    17401758      if (argc < 0) {
    17411759        struct RArray *ary = mrb_ary_ptr(regs[1]);
    1742         argv = ary->ptr;
    1743         argc = ary->len;
     1760        argv = ARY_PTR(ary);
     1761        argc = (int)ARY_LEN(ary);
    17441762        mrb_gc_protect(mrb, regs[1]);
    17451763      }
     1764
     1765      /* strict argument check */
    17461766      if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) {
    1747         if (argc >= 0) {
    1748           if (argc < m1 + m2 || (r == 0 && argc > len)) {
     1767        if (argc < m1 + m2 || (r == 0 && argc > len + kd)) {
     1768          argnum_error(mrb, m1+m2);
     1769          goto L_RAISE;
     1770        }
     1771      }
     1772      /* extract first argument array to arguments */
     1773      else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {
     1774        mrb_gc_protect(mrb, argv[0]);
     1775        argc = (int)RARRAY_LEN(argv[0]);
     1776        argv = RARRAY_PTR(argv[0]);
     1777      }
     1778
     1779      if (kd) {
     1780        /* check last arguments is hash if method takes keyword arguments */
     1781        if (argc == m1+m2) {
     1782          kdict = mrb_hash_new(mrb);
     1783          kargs = 0;
     1784        }
     1785        else {
     1786          if (argv && argc > 0 && mrb_hash_p(argv[argc-1])) {
     1787            kdict = argv[argc-1];
     1788            mrb_hash_check_kdict(mrb, kdict);
     1789          }
     1790          else if (r || argc <= m1+m2+o
     1791                   || !(mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc))) {
     1792            kdict = mrb_hash_new(mrb);
     1793            kargs = 0;
     1794          }
     1795          else {
    17491796            argnum_error(mrb, m1+m2);
    17501797            goto L_RAISE;
    17511798          }
    1752         }
    1753       }
    1754       else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {
    1755         mrb_gc_protect(mrb, argv[0]);
    1756         argc = mrb_ary_ptr(argv[0])->len;
    1757         argv = mrb_ary_ptr(argv[0])->ptr;
    1758       }
    1759       if (argc < len) {
     1799          if (MRB_ASPEC_KEY(a) > 0) {
     1800            kdict = mrb_hash_dup(mrb, kdict);
     1801          }
     1802        }
     1803      }
     1804
     1805      /* no rest arguments */
     1806      if (argc-kargs < len) {
    17601807        int mlen = m2;
    17611808        if (argc < m1+m2) {
    1762           if (m1 < argc)
    1763             mlen = argc - m1;
    1764           else
    1765             mlen = 0;
    1766         }
    1767         regs[len+1] = *blk; /* move block */
    1768         SET_NIL_VALUE(regs[argc+1]);
     1809          mlen = m1 < argc ? argc - m1 : 0;
     1810        }
     1811        regs[blk_pos] = *blk; /* move block */
     1812        if (kd) regs[len + 1] = kdict;
     1813
     1814        /* copy mandatory and optional arguments */
    17691815        if (argv0 != argv) {
    17701816          value_move(&regs[1], argv, argc-mlen); /* m1 + o */
     
    17731819          stack_clear(&regs[argc+1], m1-argc);
    17741820        }
     1821        /* copy post mandatory arguments */
    17751822        if (mlen) {
    17761823          value_move(&regs[len-m2+1], &argv[argc-mlen], mlen);
     
    17791826          stack_clear(&regs[len-m2+mlen+1], m2-mlen);
    17801827        }
     1828        /* initalize rest arguments with empty Array */
    17811829        if (r) {
    17821830          regs[m1+o+1] = mrb_ary_new_capa(mrb, 0);
    17831831        }
    1784         if (o == 0 || argc < m1+m2) pc++;
    1785         else
    1786           pc += argc - m1 - m2 + 1;
     1832        /* skip initailizer of passed arguments */
     1833        if (o > 0 && argc-kargs > m1+m2)
     1834          pc += (argc - kargs - m1 - m2)*3;
    17871835      }
    17881836      else {
    17891837        int rnum = 0;
    17901838        if (argv0 != argv) {
    1791           regs[len+1] = *blk; /* move block */
     1839          regs[blk_pos] = *blk; /* move block */
     1840          if (kd) regs[len + 1] = kdict;
    17921841          value_move(&regs[1], argv, m1+o);
    17931842        }
    17941843        if (r) {
    1795           rnum = argc-m1-o-m2;
    1796           regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o);
     1844          mrb_value ary;
     1845
     1846          rnum = argc-m1-o-m2-kargs;
     1847          ary = mrb_ary_new_from_values(mrb, rnum, argv+m1+o);
     1848          regs[m1+o+1] = ary;
    17971849        }
    17981850        if (m2) {
     
    18021854        }
    18031855        if (argv0 == argv) {
    1804           regs[len+1] = *blk; /* move block */
    1805         }
    1806         pc += o + 1;
    1807       }
    1808       mrb->c->ci->argc = len;
     1856          regs[blk_pos] = *blk; /* move block */
     1857          if (kd) regs[len + 1] = kdict;
     1858        }
     1859        pc += o*3;
     1860      }
     1861
     1862      /* format arguments for generated code */
     1863      mrb->c->ci->argc = len + kd;
     1864
    18091865      /* clear local (but non-argument) variables */
    1810       if (irep->nlocals-len-2 > 0) {
    1811         stack_clear(&regs[len+2], irep->nlocals-len-2);
     1866      if (irep->nlocals-blk_pos-1 > 0) {
     1867        stack_clear(&regs[blk_pos+1], irep->nlocals-blk_pos-1);
    18121868      }
    18131869      JUMP;
    18141870    }
    18151871
    1816     CASE(OP_KARG) {
    1817       /* A B C          R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */
    1818       /* if C == 2; raise unless kdict.empty? */
    1819       /* OP_JMP should follow to skip init code */
    1820       NEXT;
    1821     }
    1822 
    1823     CASE(OP_KDICT) {
    1824       /* A C            R(A) := kdict */
    1825       NEXT;
    1826     }
    1827 
     1872    CASE(OP_KARG, BB) {
     1873      mrb_value k = mrb_symbol_value(syms[b]);
     1874      mrb_value kdict = regs[mrb->c->ci->argc];
     1875
     1876      if (!mrb_hash_p(kdict) || !mrb_hash_key_p(mrb, kdict, k)) {
     1877        mrb_value str = mrb_format(mrb, "missing keyword: %v", k);
     1878        mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str));
     1879        goto L_RAISE;
     1880      }
     1881      regs[a] = mrb_hash_get(mrb, kdict, k);
     1882      mrb_hash_delete_key(mrb, kdict, k);
     1883      NEXT;
     1884    }
     1885
     1886    CASE(OP_KEY_P, BB) {
     1887      mrb_value k = mrb_symbol_value(syms[b]);
     1888      mrb_value kdict = regs[mrb->c->ci->argc];
     1889      mrb_bool key_p = FALSE;
     1890
     1891      if (mrb_hash_p(kdict)) {
     1892        key_p = mrb_hash_key_p(mrb, kdict, k);
     1893      }
     1894      regs[a] = mrb_bool_value(key_p);
     1895      NEXT;
     1896    }
     1897
     1898    CASE(OP_KEYEND, Z) {
     1899      mrb_value kdict = regs[mrb->c->ci->argc];
     1900
     1901      if (mrb_hash_p(kdict) && !mrb_hash_empty_p(mrb, kdict)) {
     1902        mrb_value keys = mrb_hash_keys(mrb, kdict);
     1903        mrb_value key1 = RARRAY_PTR(keys)[0];
     1904        mrb_value str = mrb_format(mrb, "unknown keyword: %v", key1);
     1905        mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str));
     1906        goto L_RAISE;
     1907      }
     1908      NEXT;
     1909    }
     1910
     1911    CASE(OP_BREAK, B) {
     1912      c = OP_R_BREAK;
     1913      goto L_RETURN;
     1914    }
     1915    CASE(OP_RETURN_BLK, B) {
     1916      c = OP_R_RETURN;
     1917      goto L_RETURN;
     1918    }
     1919    CASE(OP_RETURN, B)
     1920    c = OP_R_NORMAL;
    18281921    L_RETURN:
    1829       i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL);
    1830       /* fall through */
    1831     CASE(OP_RETURN) {
    1832       /* A B     return R(A) (B=normal,in-block return/break) */
    1833       mrb_callinfo *ci;
     1922    {
     1923       mrb_callinfo *ci;
     1924
     1925#define ecall_adjust() do {\
     1926  ptrdiff_t cioff = ci - mrb->c->cibase;\
     1927  ecall(mrb);\
     1928  ci = mrb->c->cibase + cioff;\
     1929} while (0)
    18341930
    18351931      ci = mrb->c->ci;
     
    18431939          blk = regs[ci->argc+1];
    18441940        }
    1845         if (mrb_type(blk) == MRB_TT_PROC) {
     1941        if (mrb_proc_p(blk)) {
    18461942          struct RProc *p = mrb_proc_ptr(blk);
    18471943
    1848           if (!MRB_PROC_STRICT_P(proc) &&
    1849               ci > mrb->c->cibase && p->env == ci[-1].env) {
     1944          if (!MRB_PROC_STRICT_P(p) &&
     1945              ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) {
    18501946            p->flags |= MRB_PROC_ORPHAN;
    18511947          }
     
    18551951      if (mrb->exc) {
    18561952        mrb_callinfo *ci0;
    1857         mrb_value *stk;
    18581953
    18591954      L_RAISE:
     
    18631958          goto L_RESCUE;
    18641959        }
    1865         stk = mrb->c->stack;
    18661960        while (ci[0].ridx == ci[-1].ridx) {
    18671961          cipop(mrb);
     
    18731967          ci = mrb->c->ci;
    18741968          if (ci == mrb->c->cibase) {
    1875             mrb->c->stack = stk;
    18761969            if (ci->ridx == 0) {
    18771970            L_FTOP:             /* fiber top */
     
    18831976                struct mrb_context *c = mrb->c;
    18841977
    1885                 if (c->fib) {
    1886                   mrb_write_barrier(mrb, (struct RBasic*)c->fib);
     1978                while (c->eidx > ci->epos) {
     1979                  ecall_adjust();
    18871980                }
     1981                c->status = MRB_FIBER_TERMINATED;
    18881982                mrb->c = c->prev;
    18891983                c->prev = NULL;
     
    18961990          if (ci[0].ridx == ci[-1].ridx) {
    18971991            while (mrb->c->eidx > ci->epos) {
    1898               ecall(mrb, --mrb->c->eidx);
    1899               ci = mrb->c->ci;
     1992              ecall_adjust();
    19001993            }
    19011994          }
     
    19072000        pool = irep->pool;
    19082001        syms = irep->syms;
    1909         if (ci != ci0) {
     2002        if (ci < ci0) {
    19102003          mrb->c->stack = ci[1].stackent;
    19112004        }
    1912         stack_extend(mrb, irep->nregs);
    1913         pc = mrb->c->rescue[--ci->ridx];
     2005        mrb_stack_extend(mrb, irep->nregs);
     2006        pc = irep->iseq+mrb->c->rescue[--ci->ridx];
    19142007      }
    19152008      else {
    19162009        int acc;
    19172010        mrb_value v;
    1918 
    1919         v = regs[GETARG_A(i)];
     2011        struct RProc *dst;
     2012
     2013        ci = mrb->c->ci;
     2014        v = regs[a];
    19202015        mrb_gc_protect(mrb, v);
    1921         switch (GETARG_B(i)) {
     2016        switch (c) {
    19222017        case OP_R_RETURN:
    19232018          /* Fall through to OP_R_NORMAL otherwise */
    1924           if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) {
    1925             struct REnv *e = top_env(mrb, proc);
    1926             mrb_callinfo *ce;
    1927 
    1928             if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) {
    1929               localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    1930               goto L_RAISE;
     2019          if (ci->acc >=0 && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) {
     2020            mrb_callinfo *cibase = mrb->c->cibase;
     2021            dst = top_proc(mrb, proc);
     2022
     2023            if (MRB_PROC_ENV_P(dst)) {
     2024              struct REnv *e = MRB_PROC_ENV(dst);
     2025
     2026              if (!MRB_ENV_STACK_SHARED_P(e) || (e->cxt && e->cxt != mrb->c)) {
     2027                localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
     2028                goto L_RAISE;
     2029              }
    19312030            }
    1932            
    1933             ce = mrb->c->cibase + e->cioff;
    1934             while (ci >= ce) {
    1935               if (ci->env) {
    1936                 mrb_env_unshare(mrb, ci->env);
    1937               }
     2031            while (cibase <= ci && ci->proc != dst) {
    19382032              if (ci->acc < 0) {
    19392033                localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
     
    19422036              ci--;
    19432037            }
    1944             if (ce == mrb->c->cibase) {
     2038            if (ci <= cibase) {
    19452039              localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    19462040              goto L_RAISE;
    19472041            }
    1948             mrb->c->stack = mrb->c->ci->stackent;
    1949             mrb->c->ci = ce;
    19502042            break;
    19512043          }
     2044          /* fallthrough */
    19522045        case OP_R_NORMAL:
    19532046        NORMAL_RETURN:
    19542047          if (ci == mrb->c->cibase) {
    1955             if (!mrb->c->prev) { /* toplevel return */
    1956               localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    1957               goto L_RAISE;
     2048            struct mrb_context *c = mrb->c;
     2049
     2050            if (!c->prev) { /* toplevel return */
     2051              regs[irep->nlocals] = v;
     2052              goto L_STOP;
    19582053            }
    1959             if (mrb->c->prev->ci == mrb->c->prev->cibase) {
     2054            if (c->prev->ci == c->prev->cibase) {
    19602055              mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume");
    19612056              mrb_exc_set(mrb, exc);
    19622057              goto L_RAISE;
    19632058            }
    1964             while (mrb->c->eidx > 0) {
    1965               ecall(mrb, --mrb->c->eidx);
     2059            while (c->eidx > 0) {
     2060              ecall(mrb);
    19662061            }
    19672062            /* automatic yield at the end */
    1968             mrb->c->status = MRB_FIBER_TERMINATED;
    1969             mrb->c = mrb->c->prev;
     2063            c->status = MRB_FIBER_TERMINATED;
     2064            mrb->c = c->prev;
     2065            c->prev = NULL;
    19702066            mrb->c->status = MRB_FIBER_RUNNING;
    1971           }
    1972           ci = mrb->c->ci;
     2067            ci = mrb->c->ci;
     2068          }
    19732069          break;
    19742070        case OP_R_BREAK:
    19752071          if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN;
    1976           if (MRB_PROC_ORPHAN_P(proc)) { 
     2072          if (MRB_PROC_ORPHAN_P(proc)) {
    19772073            mrb_value exc;
    19782074
     
    19832079            goto L_RAISE;
    19842080          }
    1985           if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
     2081          if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_STACK_SHARED_P(MRB_PROC_ENV(proc))) {
    19862082            goto L_BREAK_ERROR;
    19872083          }
     2084          else {
     2085            struct REnv *e = MRB_PROC_ENV(proc);
     2086
     2087            if (e->cxt != mrb->c) {
     2088              goto L_BREAK_ERROR;
     2089            }
     2090          }
     2091          while (mrb->c->eidx > mrb->c->ci->epos) {
     2092            ecall_adjust();
     2093          }
    19882094          /* break from fiber block */
    1989           if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) {
     2095          if (ci == mrb->c->cibase && ci->pc) {
    19902096            struct mrb_context *c = mrb->c;
    19912097
    1992             while (mrb->c->eidx > 0) {
    1993               ecall(mrb, --mrb->c->eidx);
    1994             }
    19952098            mrb->c = c->prev;
    19962099            c->prev = NULL;
     
    19982101          }
    19992102          if (ci->acc < 0) {
    2000             while (mrb->c->eidx > mrb->c->ci->epos) {
    2001               ecall(mrb, --mrb->c->eidx);
    2002             }
    2003             ARENA_RESTORE(mrb, ai);
     2103            mrb_gc_arena_restore(mrb, ai);
    20042104            mrb->c->vmexec = FALSE;
    20052105            mrb->exc = (struct RObject*)break_new(mrb, proc, v);
     
    20092109          if (FALSE) {
    20102110          L_BREAK:
    2011             v = ((struct RBreak*)mrb->exc)->val;
    2012             proc = ((struct RBreak*)mrb->exc)->proc;
     2111            v = mrb_break_value_get((struct RBreak*)mrb->exc);
     2112            proc = mrb_break_proc_get((struct RBreak*)mrb->exc);
    20132113            mrb->exc = NULL;
    20142114            ci = mrb->c->ci;
    20152115          }
    20162116          mrb->c->stack = ci->stackent;
    2017           mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
    2018           while (ci > mrb->c->ci) {
    2019             if (ci->env) {
    2020               mrb_env_unshare(mrb, ci->env);
    2021             }
     2117          proc = proc->upper;
     2118          while (mrb->c->cibase < ci &&  ci[-1].proc != proc) {
    20222119            if (ci[-1].acc == CI_ACC_SKIP) {
    2023               mrb->c->ci = ci;
     2120              while (ci < mrb->c->ci) {
     2121                cipop(mrb);
     2122              }
    20242123              goto L_BREAK_ERROR;
    20252124            }
    20262125            ci--;
     2126          }
     2127          if (ci == mrb->c->cibase) {
     2128            goto L_BREAK_ERROR;
    20272129          }
    20282130          break;
     
    20312133          break;
    20322134        }
    2033         while (mrb->c->eidx > mrb->c->ci->epos) {
    2034           ecall(mrb, --mrb->c->eidx);
    2035         }
    2036         if (mrb->c->vmexec && !mrb->c->ci->target_class) {
    2037           ARENA_RESTORE(mrb, ai);
     2135        while (ci < mrb->c->ci) {
     2136          cipop(mrb);
     2137        }
     2138        ci[0].ridx = ci[-1].ridx;
     2139        while (mrb->c->eidx > ci->epos) {
     2140          ecall_adjust();
     2141        }
     2142        if (mrb->c->vmexec && !ci->target_class) {
     2143          mrb_gc_arena_restore(mrb, ai);
    20382144          mrb->c->vmexec = FALSE;
    20392145          mrb->jmp = prev_jmp;
    20402146          return v;
    20412147        }
    2042         ci = mrb->c->ci;
    20432148        acc = ci->acc;
    20442149        mrb->c->stack = ci->stackent;
    20452150        cipop(mrb);
    20462151        if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
    2047           ARENA_RESTORE(mrb, ai);
     2152          mrb_gc_arena_restore(mrb, ai);
    20482153          mrb->jmp = prev_jmp;
    20492154          return v;
    20502155        }
    20512156        pc = ci->pc;
    2052         DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
     2157        ci = mrb->c->ci;
     2158        DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid)));
    20532159        proc = mrb->c->ci->proc;
    20542160        irep = proc->body.irep;
     
    20572163
    20582164        regs[acc] = v;
    2059         ARENA_RESTORE(mrb, ai);
     2165        mrb_gc_arena_restore(mrb, ai);
    20602166      }
    20612167      JUMP;
    20622168    }
    20632169
    2064     CASE(OP_TAILCALL) {
    2065       /* A B C  return call(R(A),Syms(B),R(A+1),... ,R(A+C+1)) */
    2066       int a = GETARG_A(i);
    2067       int n = GETARG_C(i);
    2068       struct RProc *m;
    2069       struct RClass *c;
    2070       mrb_callinfo *ci;
    2071       mrb_value recv;
    2072       mrb_sym mid = syms[GETARG_B(i)];
    2073 
    2074       recv = regs[a];
    2075       c = mrb_class(mrb, recv);
    2076       m = mrb_method_search_vm(mrb, &c, mid);
    2077       if (!m) {
    2078         mrb_value sym = mrb_symbol_value(mid);
    2079         mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    2080         m = mrb_method_search_vm(mrb, &c, missing);
    2081         if (!m) {
    2082           mrb_value args;
    2083 
    2084           if (n == CALL_MAXARGS) {
    2085             args = regs[a+1];
    2086           }
    2087           else {
    2088             args = mrb_ary_new_from_values(mrb, n, regs+a+1);
    2089           }
    2090           ERR_PC_SET(mrb, pc);
    2091           mrb_method_missing(mrb, mid, recv, args);
    2092         }
    2093         mid = missing;
    2094         if (n == CALL_MAXARGS) {
    2095           mrb_ary_unshift(mrb, regs[a+1], sym);
    2096         }
    2097         else {
    2098           value_move(regs+a+2, regs+a+1, ++n);
    2099           regs[a+1] = sym;
    2100         }
    2101       }
    2102 
    2103       /* replace callinfo */
    2104       ci = mrb->c->ci;
    2105       ci->mid = mid;
    2106       ci->target_class = c;
    2107       if (n == CALL_MAXARGS) {
    2108         ci->argc = -1;
    2109       }
    2110       else {
    2111         ci->argc = n;
    2112       }
    2113 
    2114       /* move stack */
    2115       value_move(mrb->c->stack, &regs[a], ci->argc+1);
    2116 
    2117       if (MRB_PROC_CFUNC_P(m)) {
    2118         mrb_value v = m->body.func(mrb, recv);
    2119         mrb->c->stack[0] = v;
    2120         mrb_gc_arena_restore(mrb, ai);
    2121         goto L_RETURN;
    2122       }
    2123       else {
    2124         /* setup environment for calling method */
    2125         irep = m->body.irep;
    2126         pool = irep->pool;
    2127         syms = irep->syms;
    2128         if (ci->argc < 0) {
    2129           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    2130         }
    2131         else {
    2132           stack_extend(mrb, irep->nregs);
    2133         }
    2134         pc = irep->iseq;
    2135       }
    2136       JUMP;
    2137     }
    2138 
    2139     CASE(OP_BLKPUSH) {
    2140       /* A Bx   R(A) := block (16=6:1:5:4) */
    2141       int a = GETARG_A(i);
    2142       int bx = GETARG_Bx(i);
    2143       int m1 = (bx>>10)&0x3f;
    2144       int r  = (bx>>9)&0x1;
    2145       int m2 = (bx>>4)&0x1f;
    2146       int lv = (bx>>0)&0xf;
     2170    CASE(OP_BLKPUSH, BS) {
     2171      int m1 = (b>>11)&0x3f;
     2172      int r  = (b>>10)&0x1;
     2173      int m2 = (b>>5)&0x1f;
     2174      int kd = (b>>4)&0x1;
     2175      int lv = (b>>0)&0xf;
    21472176      mrb_value *stack;
    21482177
     
    21502179      else {
    21512180        struct REnv *e = uvenv(mrb, lv-1);
    2152         if (!e || e->cioff == 0 ||
    2153             (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {
     2181        if (!e || (!MRB_ENV_STACK_SHARED_P(e) && e->mid == 0) ||
     2182            MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) {
    21542183          localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
    21552184          goto L_RAISE;
     
    21612190        goto L_RAISE;
    21622191      }
    2163       regs[a] = stack[m1+r+m2];
     2192      regs[a] = stack[m1+r+m2+kd];
    21642193      NEXT;
    21652194    }
    21662195
    21672196#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
    2168 #define OP_MATH_BODY(op,v1,v2) do {\
    2169   v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\
    2170 } while(0)
    2171 
    2172     CASE(OP_ADD) {
    2173       /* A B C  R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/
    2174       int a = GETARG_A(i);
     2197#define OP_MATH(op_name)                                                    \
     2198  /* need to check if op is overridden */                                   \
     2199  switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {                  \
     2200    OP_MATH_CASE_FIXNUM(op_name);                                           \
     2201    OP_MATH_CASE_FLOAT(op_name, fixnum, float);                             \
     2202    OP_MATH_CASE_FLOAT(op_name, float,  fixnum);                            \
     2203    OP_MATH_CASE_FLOAT(op_name, float,  float);                             \
     2204    OP_MATH_CASE_STRING_##op_name();                                        \
     2205    default:                                                                \
     2206      c = 1;                                                                \
     2207      mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name));       \
     2208      goto L_SEND_SYM;                                                      \
     2209  }                                                                         \
     2210  NEXT;
     2211#define OP_MATH_CASE_FIXNUM(op_name)                                        \
     2212  case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM):                                \
     2213    {                                                                       \
     2214      mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z;        \
     2215      if (mrb_int_##op_name##_overflow(x, y, &z))                           \
     2216        OP_MATH_OVERFLOW_INT(op_name, x, y, z);                             \
     2217      else                                                                  \
     2218        SET_INT_VALUE(regs[a], z);                                          \
     2219    }                                                                       \
     2220    break
     2221#ifdef MRB_WITHOUT_FLOAT
     2222#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0
     2223#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z)
     2224#else
     2225#define OP_MATH_CASE_FLOAT(op_name, t1, t2)                                     \
     2226  case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2):                                \
     2227    {                                                                           \
     2228      mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \
     2229      SET_FLOAT_VALUE(mrb, regs[a], z);                                         \
     2230    }                                                                           \
     2231    break
     2232#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \
     2233  SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y)
     2234#endif
     2235#define OP_MATH_CASE_STRING_add()                                           \
     2236  case TYPES2(MRB_TT_STRING, MRB_TT_STRING):                                \
     2237    regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);                        \
     2238    mrb_gc_arena_restore(mrb, ai);                                          \
     2239    break
     2240#define OP_MATH_CASE_STRING_sub() (void)0
     2241#define OP_MATH_CASE_STRING_mul() (void)0
     2242#define OP_MATH_OP_add +
     2243#define OP_MATH_OP_sub -
     2244#define OP_MATH_OP_mul *
     2245#define OP_MATH_TT_fixnum MRB_TT_FIXNUM
     2246#define OP_MATH_TT_float  MRB_TT_FLOAT
     2247
     2248    CASE(OP_ADD, B) {
     2249      OP_MATH(add);
     2250    }
     2251
     2252    CASE(OP_SUB, B) {
     2253      OP_MATH(sub);
     2254    }
     2255
     2256    CASE(OP_MUL, B) {
     2257      OP_MATH(mul);
     2258    }
     2259
     2260    CASE(OP_DIV, B) {
     2261#ifndef MRB_WITHOUT_FLOAT
     2262      double x, y, f;
     2263#endif
    21752264
    21762265      /* need to check if op is overridden */
    21772266      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    21782267      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
    2179         {
    2180           mrb_int x, y, z;
    2181           mrb_value *regs_a = regs + a;
    2182 
    2183           x = mrb_fixnum(regs_a[0]);
    2184           y = mrb_fixnum(regs_a[1]);
    2185           if (mrb_int_add_overflow(x, y, &z)) {
    2186             SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
    2187             break;
    2188           }
    2189           SET_INT_VALUE(regs[a], z);
    2190         }
    2191         break;
    2192       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2193         {
    2194           mrb_int x = mrb_fixnum(regs[a]);
    2195           mrb_float y = mrb_float(regs[a+1]);
    2196           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y);
    2197         }
    2198         break;
    2199       case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2200 #ifdef MRB_WORD_BOXING
    2201         {
    2202           mrb_float x = mrb_float(regs[a]);
    2203           mrb_int y = mrb_fixnum(regs[a+1]);
    2204           SET_FLOAT_VALUE(mrb, regs[a], x + y);
    2205         }
    2206 #else
    2207         OP_MATH_BODY(+,mrb_float,mrb_fixnum);
    2208 #endif
    2209         break;
    2210       case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2211 #ifdef MRB_WORD_BOXING
    2212         {
    2213           mrb_float x = mrb_float(regs[a]);
    2214           mrb_float y = mrb_float(regs[a+1]);
    2215           SET_FLOAT_VALUE(mrb, regs[a], x + y);
    2216         }
    2217 #else
    2218         OP_MATH_BODY(+,mrb_float,mrb_float);
    2219 #endif
    2220         break;
    2221       case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
    2222         regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
    2223         break;
    2224       default:
    2225         goto L_SEND;
    2226       }
    2227       ARENA_RESTORE(mrb, ai);
    2228       NEXT;
    2229     }
    2230 
    2231     CASE(OP_SUB) {
    2232       /* A B C  R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/
    2233       int a = GETARG_A(i);
    2234 
    2235       /* need to check if op is overridden */
    2236       switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    2237       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
    2238         {
    2239           mrb_int x, y, z;
    2240 
    2241           x = mrb_fixnum(regs[a]);
    2242           y = mrb_fixnum(regs[a+1]);
    2243           if (mrb_int_sub_overflow(x, y, &z)) {
    2244             SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
    2245             break;
    2246           }
    2247           SET_INT_VALUE(regs[a], z);
    2248         }
    2249         break;
    2250       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2251         {
    2252           mrb_int x = mrb_fixnum(regs[a]);
    2253           mrb_float y = mrb_float(regs[a+1]);
    2254           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y);
    2255         }
    2256         break;
    2257       case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2258 #ifdef MRB_WORD_BOXING
    2259         {
    2260           mrb_float x = mrb_float(regs[a]);
    2261           mrb_int y = mrb_fixnum(regs[a+1]);
    2262           SET_FLOAT_VALUE(mrb, regs[a], x - y);
    2263         }
    2264 #else
    2265         OP_MATH_BODY(-,mrb_float,mrb_fixnum);
    2266 #endif
    2267         break;
    2268       case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2269 #ifdef MRB_WORD_BOXING
    2270         {
    2271           mrb_float x = mrb_float(regs[a]);
    2272           mrb_float y = mrb_float(regs[a+1]);
    2273           SET_FLOAT_VALUE(mrb, regs[a], x - y);
    2274         }
    2275 #else
    2276         OP_MATH_BODY(-,mrb_float,mrb_float);
    2277 #endif
    2278         break;
    2279       default:
    2280         goto L_SEND;
    2281       }
    2282       NEXT;
    2283     }
    2284 
    2285     CASE(OP_MUL) {
    2286       /* A B C  R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/
    2287       int a = GETARG_A(i);
    2288 
    2289       /* need to check if op is overridden */
    2290       switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    2291       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
    2292         {
    2293           mrb_int x, y, z;
    2294 
    2295           x = mrb_fixnum(regs[a]);
    2296           y = mrb_fixnum(regs[a+1]);
    2297           if (mrb_int_mul_overflow(x, y, &z)) {
    2298             SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
    2299             break;
    2300           }
    2301           SET_INT_VALUE(regs[a], z);
    2302         }
    2303         break;
    2304       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2305         {
    2306           mrb_int x = mrb_fixnum(regs[a]);
    2307           mrb_float y = mrb_float(regs[a+1]);
    2308           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y);
    2309         }
    2310         break;
    2311       case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2312 #ifdef MRB_WORD_BOXING
    2313         {
    2314           mrb_float x = mrb_float(regs[a]);
    2315           mrb_int y = mrb_fixnum(regs[a+1]);
    2316           SET_FLOAT_VALUE(mrb, regs[a], x * y);
    2317         }
    2318 #else
    2319         OP_MATH_BODY(*,mrb_float,mrb_fixnum);
    2320 #endif
    2321         break;
    2322       case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2323 #ifdef MRB_WORD_BOXING
    2324         {
    2325           mrb_float x = mrb_float(regs[a]);
    2326           mrb_float y = mrb_float(regs[a+1]);
    2327           SET_FLOAT_VALUE(mrb, regs[a], x * y);
    2328         }
    2329 #else
    2330         OP_MATH_BODY(*,mrb_float,mrb_float);
    2331 #endif
    2332         break;
    2333       default:
    2334         goto L_SEND;
    2335       }
    2336       NEXT;
    2337     }
    2338 
    2339     CASE(OP_DIV) {
    2340       /* A B C  R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
    2341       int a = GETARG_A(i);
    2342 
    2343       /* need to check if op is overridden */
    2344       switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    2345       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
     2268#ifdef MRB_WITHOUT_FLOAT
    23462269        {
    23472270          mrb_int x = mrb_fixnum(regs[a]);
    23482271          mrb_int y = mrb_fixnum(regs[a+1]);
    2349           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y);
    2350         }
     2272          SET_INT_VALUE(regs[a], y ? x / y : 0);
     2273        }
     2274        break;
     2275#else
     2276        x = (mrb_float)mrb_fixnum(regs[a]);
     2277        y = (mrb_float)mrb_fixnum(regs[a+1]);
    23512278        break;
    23522279      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2353         {
    2354           mrb_int x = mrb_fixnum(regs[a]);
    2355           mrb_float y = mrb_float(regs[a+1]);
    2356           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y);
    2357         }
     2280        x = (mrb_float)mrb_fixnum(regs[a]);
     2281        y = mrb_float(regs[a+1]);
    23582282        break;
    23592283      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2360 #ifdef MRB_WORD_BOXING
    2361         {
    2362           mrb_float x = mrb_float(regs[a]);
    2363           mrb_int y = mrb_fixnum(regs[a+1]);
    2364           SET_FLOAT_VALUE(mrb, regs[a], x / y);
    2365         }
    2366 #else
    2367         OP_MATH_BODY(/,mrb_float,mrb_fixnum);
    2368 #endif
     2284        x = mrb_float(regs[a]);
     2285        y = (mrb_float)mrb_fixnum(regs[a+1]);
    23692286        break;
    23702287      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2371 #ifdef MRB_WORD_BOXING
    2372         {
    2373           mrb_float x = mrb_float(regs[a]);
    2374           mrb_float y = mrb_float(regs[a+1]);
    2375           SET_FLOAT_VALUE(mrb, regs[a], x / y);
    2376         }
     2288        x = mrb_float(regs[a]);
     2289        y = mrb_float(regs[a+1]);
     2290        break;
     2291#endif
     2292      default:
     2293        c = 1;
     2294        mid = mrb_intern_lit(mrb, "/");
     2295        goto L_SEND_SYM;
     2296      }
     2297
     2298#ifndef MRB_WITHOUT_FLOAT
     2299      if (y == 0) {
     2300        if (x > 0) f = INFINITY;
     2301        else if (x < 0) f = -INFINITY;
     2302        else /* if (x == 0) */ f = NAN;
     2303      }
     2304      else {
     2305        f = x / y;
     2306      }
     2307      SET_FLOAT_VALUE(mrb, regs[a], f);
     2308#endif
     2309      NEXT;
     2310    }
     2311
     2312#define OP_MATHI(op_name)                                                   \
     2313  /* need to check if op is overridden */                                   \
     2314  switch (mrb_type(regs[a])) {                                              \
     2315    OP_MATHI_CASE_FIXNUM(op_name);                                          \
     2316    OP_MATHI_CASE_FLOAT(op_name);                                           \
     2317    default:                                                                \
     2318      SET_INT_VALUE(regs[a+1], b);                                          \
     2319      c = 1;                                                                \
     2320      mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name));       \
     2321      goto L_SEND_SYM;                                                      \
     2322  }                                                                         \
     2323  NEXT;
     2324#define OP_MATHI_CASE_FIXNUM(op_name)                                       \
     2325  case MRB_TT_FIXNUM:                                                       \
     2326    {                                                                       \
     2327      mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z;                   \
     2328      if (mrb_int_##op_name##_overflow(x, y, &z))                           \
     2329        OP_MATH_OVERFLOW_INT(op_name, x, y, z);                             \
     2330      else                                                                  \
     2331        SET_INT_VALUE(regs[a], z);                                          \
     2332    }                                                                       \
     2333    break
     2334#ifdef MRB_WITHOUT_FLOAT
     2335#define OP_MATHI_CASE_FLOAT(op_name) (void)0
    23772336#else
    2378         OP_MATH_BODY(/,mrb_float,mrb_float);
    2379 #endif
    2380         break;
    2381       default:
    2382         goto L_SEND;
    2383       }
    2384 #ifdef MRB_NAN_BOXING
    2385       if (isnan(mrb_float(regs[a]))) {
    2386         mrb_value v = mrb_float_value(mrb, mrb_float(regs[a]));
    2387         regs[a] = v;
    2388       }
    2389 #endif
    2390       NEXT;
    2391     }
    2392 
    2393     CASE(OP_ADDI) {
    2394       /* A B C  R(A) := R(A)+C (Syms[B]=:+)*/
    2395       int a = GETARG_A(i);
    2396 
    2397       /* need to check if + is overridden */
    2398       switch (mrb_type(regs[a])) {
    2399       case MRB_TT_FIXNUM:
    2400         {
    2401           mrb_int x = mrb_fixnum(regs[a]);
    2402           mrb_int y = GETARG_C(i);
    2403           mrb_int z;
    2404 
    2405           if (mrb_int_add_overflow(x, y, &z)) {
    2406             SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
    2407             break;
    2408           }
    2409           SET_INT_VALUE(regs[a], z);
    2410         }
    2411         break;
    2412       case MRB_TT_FLOAT:
    2413 #ifdef MRB_WORD_BOXING
    2414         {
    2415           mrb_float x = mrb_float(regs[a]);
    2416           SET_FLOAT_VALUE(mrb, regs[a], x + GETARG_C(i));
    2417         }
     2337#define OP_MATHI_CASE_FLOAT(op_name)                                        \
     2338  case MRB_TT_FLOAT:                                                        \
     2339    {                                                                       \
     2340      mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b;              \
     2341      SET_FLOAT_VALUE(mrb, regs[a], z);                                     \
     2342    }                                                                       \
     2343    break
     2344#endif
     2345
     2346    CASE(OP_ADDI, BB) {
     2347      OP_MATHI(add);
     2348    }
     2349
     2350    CASE(OP_SUBI, BB) {
     2351      OP_MATHI(sub);
     2352    }
     2353
     2354#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
     2355
     2356#ifdef MRB_WITHOUT_FLOAT
     2357#define OP_CMP(op) do {\
     2358  int result;\
     2359  /* need to check if - is overridden */\
     2360  switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\
     2361  case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\
     2362    result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\
     2363    break;\
     2364  default:\
     2365    c = 1;\
     2366    mid = mrb_intern_lit(mrb, # op);\
     2367    goto L_SEND_SYM;\
     2368  }\
     2369  if (result) {\
     2370    SET_TRUE_VALUE(regs[a]);\
     2371  }\
     2372  else {\
     2373    SET_FALSE_VALUE(regs[a]);\
     2374  }\
     2375} while(0)
    24182376#else
    2419         mrb_float(regs[a]) += GETARG_C(i);
    2420 #endif
    2421         break;
    2422       default:
    2423         SET_INT_VALUE(regs[a+1], GETARG_C(i));
    2424         i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
    2425         goto L_SEND;
    2426       }
    2427       NEXT;
    2428     }
    2429 
    2430     CASE(OP_SUBI) {
    2431       /* A B C  R(A) := R(A)-C (Syms[B]=:-)*/
    2432       int a = GETARG_A(i);
    2433       mrb_value *regs_a = regs + a;
    2434 
    2435       /* need to check if + is overridden */
    2436       switch (mrb_type(regs_a[0])) {
    2437       case MRB_TT_FIXNUM:
    2438         {
    2439           mrb_int x = mrb_fixnum(regs_a[0]);
    2440           mrb_int y = GETARG_C(i);
    2441           mrb_int z;
    2442 
    2443           if (mrb_int_sub_overflow(x, y, &z)) {
    2444             SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
    2445           }
    2446           else {
    2447             SET_INT_VALUE(regs_a[0], z);
    2448           }
    2449         }
    2450         break;
    2451       case MRB_TT_FLOAT:
    2452 #ifdef MRB_WORD_BOXING
    2453         {
    2454           mrb_float x = mrb_float(regs[a]);
    2455           SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i));
    2456         }
    2457 #else
    2458         mrb_float(regs_a[0]) -= GETARG_C(i);
    2459 #endif
    2460         break;
    2461       default:
    2462         SET_INT_VALUE(regs_a[1], GETARG_C(i));
    2463         i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
    2464         goto L_SEND;
    2465       }
    2466       NEXT;
    2467     }
    2468 
    2469 #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
    2470 
    24712377#define OP_CMP(op) do {\
    24722378  int result;\
     
    24862392    break;\
    24872393  default:\
    2488     goto L_SEND;\
     2394    c = 1;\
     2395    mid = mrb_intern_lit(mrb, # op);\
     2396    goto L_SEND_SYM;\
    24892397  }\
    24902398  if (result) {\
     
    24952403  }\
    24962404} while(0)
    2497 
    2498     CASE(OP_EQ) {
    2499       /* A B C  R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/
    2500       int a = GETARG_A(i);
     2405#endif
     2406
     2407    CASE(OP_EQ, B) {
    25012408      if (mrb_obj_eq(mrb, regs[a], regs[a+1])) {
    25022409        SET_TRUE_VALUE(regs[a]);
     
    25082415    }
    25092416
    2510     CASE(OP_LT) {
    2511       /* A B C  R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1)*/
    2512       int a = GETARG_A(i);
     2417    CASE(OP_LT, B) {
    25132418      OP_CMP(<);
    25142419      NEXT;
    25152420    }
    25162421
    2517     CASE(OP_LE) {
    2518       /* A B C  R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)*/
    2519       int a = GETARG_A(i);
     2422    CASE(OP_LE, B) {
    25202423      OP_CMP(<=);
    25212424      NEXT;
    25222425    }
    25232426
    2524     CASE(OP_GT) {
    2525       /* A B C  R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1)*/
    2526       int a = GETARG_A(i);
     2427    CASE(OP_GT, B) {
    25272428      OP_CMP(>);
    25282429      NEXT;
    25292430    }
    25302431
    2531     CASE(OP_GE) {
    2532       /* A B C  R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)*/
    2533       int a = GETARG_A(i);
     2432    CASE(OP_GE, B) {
    25342433      OP_CMP(>=);
    25352434      NEXT;
    25362435    }
    25372436
    2538     CASE(OP_ARRAY) {
    2539       /* A B C          R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
    2540       int a = GETARG_A(i);
    2541       int b = GETARG_B(i);
    2542       int c = GETARG_C(i);
     2437    CASE(OP_ARRAY, BB) {
     2438      mrb_value v = mrb_ary_new_from_values(mrb, b, &regs[a]);
     2439      regs[a] = v;
     2440      mrb_gc_arena_restore(mrb, ai);
     2441      NEXT;
     2442    }
     2443    CASE(OP_ARRAY2, BBB) {
    25432444      mrb_value v = mrb_ary_new_from_values(mrb, c, &regs[b]);
    25442445      regs[a] = v;
    2545       ARENA_RESTORE(mrb, ai);
    2546       NEXT;
    2547     }
    2548 
    2549     CASE(OP_ARYCAT) {
    2550       /* A B            mrb_ary_concat(R(A),R(B)) */
    2551       int a = GETARG_A(i);
    2552       int b = GETARG_B(i);
    2553       mrb_value splat = mrb_ary_splat(mrb, regs[b]);
    2554       mrb_ary_concat(mrb, regs[a], splat);
    2555       ARENA_RESTORE(mrb, ai);
    2556       NEXT;
    2557     }
    2558 
    2559     CASE(OP_ARYPUSH) {
    2560       /* A B            R(A).push(R(B)) */
    2561       int a = GETARG_A(i);
    2562       int b = GETARG_B(i);
    2563       mrb_ary_push(mrb, regs[a], regs[b]);
    2564       NEXT;
    2565     }
    2566 
    2567     CASE(OP_AREF) {
    2568       /* A B C          R(A) := R(B)[C] */
    2569       int a = GETARG_A(i);
    2570       int b = GETARG_B(i);
    2571       int c = GETARG_C(i);
     2446      mrb_gc_arena_restore(mrb, ai);
     2447      NEXT;
     2448    }
     2449
     2450    CASE(OP_ARYCAT, B) {
     2451      mrb_value splat = mrb_ary_splat(mrb, regs[a+1]);
     2452      if (mrb_nil_p(regs[a])) {
     2453        regs[a] = splat;
     2454      }
     2455      else {
     2456        mrb_ary_concat(mrb, regs[a], splat);
     2457      }
     2458      mrb_gc_arena_restore(mrb, ai);
     2459      NEXT;
     2460    }
     2461
     2462    CASE(OP_ARYPUSH, B) {
     2463      mrb_ary_push(mrb, regs[a], regs[a+1]);
     2464      NEXT;
     2465    }
     2466
     2467    CASE(OP_ARYDUP, B) {
     2468      mrb_value ary = regs[a];
     2469      if (mrb_array_p(ary)) {
     2470        ary = mrb_ary_new_from_values(mrb, RARRAY_LEN(ary), RARRAY_PTR(ary));
     2471      }
     2472      else {
     2473        ary = mrb_ary_new_from_values(mrb, 1, &ary);
     2474      }
     2475      regs[a] = ary;
     2476      NEXT;
     2477    }
     2478
     2479    CASE(OP_AREF, BBB) {
    25722480      mrb_value v = regs[b];
    25732481
     
    25872495    }
    25882496
    2589     CASE(OP_ASET) {
    2590       /* A B C          R(B)[C] := R(A) */
    2591       int a = GETARG_A(i);
    2592       int b = GETARG_B(i);
    2593       int c = GETARG_C(i);
     2497    CASE(OP_ASET, BBB) {
    25942498      mrb_ary_set(mrb, regs[b], c, regs[a]);
    25952499      NEXT;
    25962500    }
    25972501
    2598     CASE(OP_APOST) {
    2599       /* A B C  *R(A),R(A+1)..R(A+C) := R(A) */
    2600       int a = GETARG_A(i);
     2502    CASE(OP_APOST, BBB) {
    26012503      mrb_value v = regs[a];
    2602       int pre  = GETARG_B(i);
    2603       int post = GETARG_C(i);
     2504      int pre  = b;
     2505      int post = c;
    26042506      struct RArray *ary;
    26052507      int len, idx;
     
    26092511      }
    26102512      ary = mrb_ary_ptr(v);
    2611       len = ary->len;
     2513      len = (int)ARY_LEN(ary);
    26122514      if (len > pre + post) {
    2613         v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
     2515        v = mrb_ary_new_from_values(mrb, len - pre - post, ARY_PTR(ary)+pre);
    26142516        regs[a++] = v;
    26152517        while (post--) {
    2616           regs[a++] = ary->ptr[len-post-1];
     2518          regs[a++] = ARY_PTR(ary)[len-post-1];
    26172519        }
    26182520      }
     
    26212523        regs[a++] = v;
    26222524        for (idx=0; idx+pre<len; idx++) {
    2623           regs[a+idx] = ary->ptr[pre+idx];
     2525          regs[a+idx] = ARY_PTR(ary)[pre+idx];
    26242526        }
    26252527        while (idx < post) {
     
    26282530        }
    26292531      }
    2630       ARENA_RESTORE(mrb, ai);
    2631       NEXT;
    2632     }
    2633 
    2634     CASE(OP_STRING) {
    2635       /* A Bx           R(A) := str_new(Lit(Bx)) */
    2636       mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
    2637       regs[GETARG_A(i)] = str;
    2638       ARENA_RESTORE(mrb, ai);
    2639       NEXT;
    2640     }
    2641 
    2642     CASE(OP_STRCAT) {
    2643       /* A B    R(A).concat(R(B)) */
    2644       mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]);
    2645       NEXT;
    2646     }
    2647 
    2648     CASE(OP_HASH) {
    2649       /* A B C   R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
    2650       int b = GETARG_B(i);
    2651       int c = GETARG_C(i);
    2652       int lim = b+c*2;
    2653       mrb_value hash = mrb_hash_new_capa(mrb, c);
    2654 
    2655       while (b < lim) {
    2656         mrb_hash_set(mrb, hash, regs[b], regs[b+1]);
    2657         b+=2;
    2658       }
    2659       regs[GETARG_A(i)] = hash;
    2660       ARENA_RESTORE(mrb, ai);
    2661       NEXT;
    2662     }
    2663 
    2664     CASE(OP_LAMBDA) {
    2665       /* A b c  R(A) := lambda(SEQ[b],c) (b:c = 14:2) */
     2532      mrb_gc_arena_restore(mrb, ai);
     2533      NEXT;
     2534    }
     2535
     2536    CASE(OP_INTERN, B) {
     2537      mrb_sym sym = mrb_intern_str(mrb, regs[a]);
     2538
     2539      regs[a] = mrb_symbol_value(sym);
     2540      mrb_gc_arena_restore(mrb, ai);
     2541      NEXT;
     2542    }
     2543
     2544    CASE(OP_STRING, BB) {
     2545      mrb_value str = mrb_str_dup(mrb, pool[b]);
     2546
     2547      regs[a] = str;
     2548      mrb_gc_arena_restore(mrb, ai);
     2549      NEXT;
     2550    }
     2551
     2552    CASE(OP_STRCAT, B) {
     2553      mrb_str_concat(mrb, regs[a], regs[a+1]);
     2554      NEXT;
     2555    }
     2556
     2557    CASE(OP_HASH, BB) {
     2558      mrb_value hash = mrb_hash_new_capa(mrb, b);
     2559      int i;
     2560      int lim = a+b*2;
     2561
     2562      for (i=a; i<lim; i+=2) {
     2563        mrb_hash_set(mrb, hash, regs[i], regs[i+1]);
     2564      }
     2565      regs[a] = hash;
     2566      mrb_gc_arena_restore(mrb, ai);
     2567      NEXT;
     2568    }
     2569
     2570    CASE(OP_HASHADD, BB) {
     2571      mrb_value hash;
     2572      int i;
     2573      int lim = a+b*2+1;
     2574
     2575      hash = mrb_ensure_hash_type(mrb, regs[a]);
     2576      for (i=a+1; i<lim; i+=2) {
     2577        mrb_hash_set(mrb, hash, regs[i], regs[i+1]);
     2578      }
     2579      mrb_gc_arena_restore(mrb, ai);
     2580      NEXT;
     2581    }
     2582    CASE(OP_HASHCAT, B) {
     2583      mrb_value hash = mrb_ensure_hash_type(mrb, regs[a]);
     2584
     2585      mrb_hash_merge(mrb, hash, regs[a+1]);
     2586      mrb_gc_arena_restore(mrb, ai);
     2587      NEXT;
     2588    }
     2589
     2590    CASE(OP_LAMBDA, BB)
     2591    c = OP_L_LAMBDA;
     2592    L_MAKE_LAMBDA:
     2593    {
    26662594      struct RProc *p;
    2667       int c = GETARG_c(i);
     2595      mrb_irep *nirep = irep->reps[b];
    26682596
    26692597      if (c & OP_L_CAPTURE) {
    2670         p = mrb_closure_new(mrb, irep->reps[GETARG_b(i)]);
     2598        p = mrb_closure_new(mrb, nirep);
    26712599      }
    26722600      else {
    2673         p = mrb_proc_new(mrb, irep->reps[GETARG_b(i)]);
     2601        p = mrb_proc_new(mrb, nirep);
     2602        p->flags |= MRB_PROC_SCOPE;
    26742603      }
    26752604      if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT;
    2676       regs[GETARG_A(i)] = mrb_obj_value(p);
    2677       ARENA_RESTORE(mrb, ai);
    2678       NEXT;
    2679     }
    2680 
    2681     CASE(OP_OCLASS) {
    2682       /* A      R(A) := ::Object */
    2683       regs[GETARG_A(i)] = mrb_obj_value(mrb->object_class);
    2684       NEXT;
    2685     }
    2686 
    2687     CASE(OP_CLASS) {
    2688       /* A B    R(A) := newclass(R(A),Syms(B),R(A+1)) */
     2605      regs[a] = mrb_obj_value(p);
     2606      mrb_gc_arena_restore(mrb, ai);
     2607      NEXT;
     2608    }
     2609    CASE(OP_BLOCK, BB) {
     2610      c = OP_L_BLOCK;
     2611      goto L_MAKE_LAMBDA;
     2612    }
     2613    CASE(OP_METHOD, BB) {
     2614      c = OP_L_METHOD;
     2615      goto L_MAKE_LAMBDA;
     2616    }
     2617
     2618    CASE(OP_RANGE_INC, B) {
     2619      mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], FALSE);
     2620      regs[a] = val;
     2621      mrb_gc_arena_restore(mrb, ai);
     2622      NEXT;
     2623    }
     2624
     2625    CASE(OP_RANGE_EXC, B) {
     2626      mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], TRUE);
     2627      regs[a] = val;
     2628      mrb_gc_arena_restore(mrb, ai);
     2629      NEXT;
     2630    }
     2631
     2632    CASE(OP_OCLASS, B) {
     2633      regs[a] = mrb_obj_value(mrb->object_class);
     2634      NEXT;
     2635    }
     2636
     2637    CASE(OP_CLASS, BB) {
    26892638      struct RClass *c = 0, *baseclass;
    2690       int a = GETARG_A(i);
    26912639      mrb_value base, super;
    2692       mrb_sym id = syms[GETARG_B(i)];
     2640      mrb_sym id = syms[b];
    26932641
    26942642      base = regs[a];
    26952643      super = regs[a+1];
    26962644      if (mrb_nil_p(base)) {
    2697         baseclass = mrb->c->ci->proc->target_class;
    2698         if (!baseclass) baseclass = mrb->c->ci->target_class;
    2699 
     2645        baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
    27002646        base = mrb_obj_value(baseclass);
    27012647      }
    27022648      c = mrb_vm_define_class(mrb, base, super, id);
    27032649      regs[a] = mrb_obj_value(c);
    2704       ARENA_RESTORE(mrb, ai);
    2705       NEXT;
    2706     }
    2707 
    2708     CASE(OP_MODULE) {
    2709       /* A B            R(A) := newmodule(R(A),Syms(B)) */
    2710       struct RClass *c = 0, *baseclass;
    2711       int a = GETARG_A(i);
     2650      mrb_gc_arena_restore(mrb, ai);
     2651      NEXT;
     2652    }
     2653
     2654    CASE(OP_MODULE, BB) {
     2655      struct RClass *cls = 0, *baseclass;
    27122656      mrb_value base;
    2713       mrb_sym id = syms[GETARG_B(i)];
     2657      mrb_sym id = syms[b];
    27142658
    27152659      base = regs[a];
    27162660      if (mrb_nil_p(base)) {
    2717         baseclass = mrb->c->ci->proc->target_class;
    2718         if (!baseclass) baseclass = mrb->c->ci->target_class;
    2719 
     2661        baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
    27202662        base = mrb_obj_value(baseclass);
    27212663      }
    2722       c = mrb_vm_define_module(mrb, base, id);
    2723       regs[a] = mrb_obj_value(c);
    2724       ARENA_RESTORE(mrb, ai);
    2725       NEXT;
    2726     }
    2727 
    2728     CASE(OP_EXEC) {
    2729       /* A Bx   R(A) := blockexec(R(A),SEQ[Bx]) */
    2730       int a = GETARG_A(i);
     2664      cls = mrb_vm_define_module(mrb, base, id);
     2665      regs[a] = mrb_obj_value(cls);
     2666      mrb_gc_arena_restore(mrb, ai);
     2667      NEXT;
     2668    }
     2669
     2670    CASE(OP_EXEC, BB) {
    27312671      mrb_callinfo *ci;
    27322672      mrb_value recv = regs[a];
    27332673      struct RProc *p;
     2674      mrb_irep *nirep = irep->reps[b];
    27342675
    27352676      /* prepare closure */
    2736       p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
     2677      p = mrb_proc_new(mrb, nirep);
    27372678      p->c = NULL;
    2738 
    2739       /* prepare stack */
     2679      mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)proc);
     2680      MRB_PROC_SET_TARGET_CLASS(p, mrb_class_ptr(recv));
     2681      p->flags |= MRB_PROC_SCOPE;
     2682
     2683      /* prepare call stack */
    27402684      ci = cipush(mrb);
    2741       ci->pc = pc + 1;
     2685      ci->pc = pc;
    27422686      ci->acc = a;
    27432687      ci->mid = 0;
     
    27492693      mrb->c->stack += a;
    27502694
    2751       /* setup closure */
    2752       p->target_class = ci->target_class;
     2695      /* setup block to call */
    27532696      ci->proc = p;
    27542697
     
    27562699      pool = irep->pool;
    27572700      syms = irep->syms;
    2758       stack_extend(mrb, irep->nregs);
     2701      mrb_stack_extend(mrb, irep->nregs);
    27592702      stack_clear(regs+1, irep->nregs-1);
    2760       ci->nregs = irep->nregs;
    27612703      pc = irep->iseq;
    27622704      JUMP;
    27632705    }
    27642706
    2765     CASE(OP_METHOD) {
    2766       /* A B            R(A).newmethod(Syms(B),R(A+1)) */
    2767       int a = GETARG_A(i);
    2768       struct RClass *c = mrb_class_ptr(regs[a]);
     2707    CASE(OP_DEF, BB) {
     2708      struct RClass *target = mrb_class_ptr(regs[a]);
    27692709      struct RProc *p = mrb_proc_ptr(regs[a+1]);
    2770 
    2771       mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p);
    2772       ARENA_RESTORE(mrb, ai);
    2773       NEXT;
    2774     }
    2775 
    2776     CASE(OP_SCLASS) {
    2777       /* A B    R(A) := R(B).singleton_class */
    2778       regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]);
    2779       ARENA_RESTORE(mrb, ai);
    2780       NEXT;
    2781     }
    2782 
    2783     CASE(OP_TCLASS) {
    2784       /* A      R(A) := target_class */
    2785       if (!mrb->c->ci->target_class) {
    2786         mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
    2787         mrb_exc_set(mrb, exc);
    2788         goto L_RAISE;
    2789       }
    2790       regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class);
    2791       NEXT;
    2792     }
    2793 
    2794     CASE(OP_RANGE) {
    2795       /* A B C  R(A) := range_new(R(B),R(B+1),C) */
    2796       int b = GETARG_B(i);
    2797       mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
    2798       regs[GETARG_A(i)] = val;
    2799       ARENA_RESTORE(mrb, ai);
    2800       NEXT;
    2801     }
    2802 
    2803     CASE(OP_DEBUG) {
    2804       /* A B C    debug print R(A),R(B),R(C) */
     2710      mrb_method_t m;
     2711
     2712      MRB_METHOD_FROM_PROC(m, p);
     2713      mrb_define_method_raw(mrb, target, syms[b], m);
     2714      mrb_gc_arena_restore(mrb, ai);
     2715      NEXT;
     2716    }
     2717
     2718    CASE(OP_SCLASS, B) {
     2719      regs[a] = mrb_singleton_class(mrb, regs[a]);
     2720      mrb_gc_arena_restore(mrb, ai);
     2721      NEXT;
     2722    }
     2723
     2724    CASE(OP_TCLASS, B) {
     2725      if (!check_target_class(mrb)) goto L_RAISE;
     2726      regs[a] = mrb_obj_value(mrb->c->ci->target_class);
     2727      NEXT;
     2728    }
     2729
     2730    CASE(OP_ALIAS, BB) {
     2731      struct RClass *target;
     2732
     2733      if (!check_target_class(mrb)) goto L_RAISE;
     2734      target = mrb->c->ci->target_class;
     2735      mrb_alias_method(mrb, target, syms[a], syms[b]);
     2736      NEXT;
     2737    }
     2738    CASE(OP_UNDEF, B) {
     2739      struct RClass *target;
     2740
     2741      if (!check_target_class(mrb)) goto L_RAISE;
     2742      target = mrb->c->ci->target_class;
     2743      mrb_undef_method_id(mrb, target, syms[a]);
     2744      NEXT;
     2745    }
     2746
     2747    CASE(OP_DEBUG, Z) {
     2748      FETCH_BBB();
    28052749#ifdef MRB_ENABLE_DEBUG_HOOK
    28062750      mrb->debug_op_hook(mrb, irep, pc, regs);
    28072751#else
    28082752#ifndef MRB_DISABLE_STDIO
    2809       printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i));
     2753      printf("OP_DEBUG %d %d %d\n", a, b, c);
    28102754#else
    28112755      abort();
     
    28152759    }
    28162760
    2817     CASE(OP_STOP) {
     2761    CASE(OP_ERR, B) {
     2762      mrb_value msg = mrb_str_dup(mrb, pool[a]);
     2763      mrb_value exc;
     2764
     2765      exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
     2766      ERR_PC_SET(mrb);
     2767      mrb_exc_set(mrb, exc);
     2768      goto L_RAISE;
     2769    }
     2770
     2771    CASE(OP_EXT1, Z) {
     2772      insn = READ_B();
     2773      switch (insn) {
     2774#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _1(); goto L_OP_ ## insn ## _BODY;
     2775#include "mruby/ops.h"
     2776#undef OPCODE
     2777      }
     2778      pc--;
     2779      NEXT;
     2780    }
     2781    CASE(OP_EXT2, Z) {
     2782      insn = READ_B();
     2783      switch (insn) {
     2784#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _2(); goto L_OP_ ## insn ## _BODY;
     2785#include "mruby/ops.h"
     2786#undef OPCODE
     2787      }
     2788      pc--;
     2789      NEXT;
     2790    }
     2791    CASE(OP_EXT3, Z) {
     2792      uint8_t insn = READ_B();
     2793      switch (insn) {
     2794#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _3(); goto L_OP_ ## insn ## _BODY;
     2795#include "mruby/ops.h"
     2796#undef OPCODE
     2797      }
     2798      pc--;
     2799      NEXT;
     2800    }
     2801
     2802    CASE(OP_STOP, Z) {
    28182803      /*        stop VM */
    28192804    L_STOP:
    2820       {
    2821         int epos = mrb->c->ci->epos;
    2822 
    2823         while (mrb->c->eidx > epos) {
    2824           ecall(mrb, --mrb->c->eidx);
    2825         }
    2826       }
     2805      while (mrb->c->eidx > 0) {
     2806        ecall(mrb);
     2807      }
     2808      mrb->c->cibase->ridx = 0;
    28272809      ERR_PC_CLR(mrb);
    28282810      mrb->jmp = prev_jmp;
     
    28322814      return regs[irep->nlocals];
    28332815    }
    2834 
    2835     CASE(OP_ERR) {
    2836       /* Bx     raise RuntimeError with message Lit(Bx) */
    2837       mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
    2838       mrb_value exc;
    2839 
    2840       if (GETARG_A(i) == 0) {
    2841         exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg);
    2842       }
    2843       else {
    2844         exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
    2845       }
    2846       mrb_exc_set(mrb, exc);
    2847       goto L_RAISE;
    2848     }
    28492816  }
    28502817  END_DISPATCH;
    28512818#undef regs
    2852 
    28532819  }
    28542820  MRB_CATCH(&c_jmp) {
     
    28842850  }
    28852851  ci = cipush(mrb);
     2852  ci->stackent = mrb->c->stack;
    28862853  ci->mid = 0;
    2887   ci->nregs = 1;   /* protect the receiver */
    28882854  ci->acc = CI_ACC_SKIP;
    28892855  ci->target_class = mrb->object_class;
    28902856  v = mrb_vm_run(mrb, proc, self, stack_keep);
    2891   cipop(mrb);
    28922857
    28932858  return v;
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/gitlab.rake

    r331 r439  
    6464  [true, false].each do |mode_32|
    6565    ['', 'MRB_USE_FLOAT'].each do |float_conf|
    66       ['', 'MRB_INT16', 'MRB_INT64'].each do |int_conf|
    67         ['', 'MRB_NAN_BOXING', 'MRB_WORD_BOXING'].each do |boxing_conf|
    68           ['', 'MRB_UTF8_STRING'].each do |utf8_conf|
    69             next if (float_conf == 'MRB_USE_FLOAT') && (boxing_conf == 'MRB_NAN_BOXING')
    70             next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_NAN_BOXING')
    71             next if (int_conf == 'MRB_INT16') && (boxing_conf == 'MRB_WORD_BOXING')
    72             next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_WORD_BOXING') && mode_32
    73             env = [float_conf, int_conf, boxing_conf, utf8_conf].map do |conf|
    74               conf == '' ? nil : "-D#{conf}=1"
    75             end.compact.join(' ')
    76             bit = mode_32 ? '-m32 ' : ''
    77             _info = ''
    78             _info += mode_32 ? '32bit ' : '64bit '
    79             _info += float_conf['USE'] ? 'float ' : ''
    80             _info += int_conf['16'] ? 'int16 ' : ''
    81             _info += int_conf['64'] ? 'int64 ' : ''
    82             _info += boxing_conf['NAN'] ? 'nan ' : ''
    83             _info += boxing_conf['word'] ? 'word ' : ''
    84             _info += utf8_conf['UTF8'] ? 'utf8 ' : ''
    85             _info = _info.gsub(/ +/, ' ').strip.tr(' ', '_')
    86             configs << { '_info' => _info, 'CFLAGS' => "#{bit}#{env}", 'LDFLAGS' => bit.strip.to_s }
    87           end
     66      ['', 'MRB_NAN_BOXING', 'MRB_WORD_BOXING'].each do |boxing_conf|
     67        ['', 'MRB_UTF8_STRING'].each do |utf8_conf|
     68          next if (float_conf == 'MRB_USE_FLOAT') && (boxing_conf == 'MRB_NAN_BOXING')
     69          next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_NAN_BOXING')
     70          next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_WORD_BOXING') && mode_32
     71          env = [float_conf, int_conf, boxing_conf, utf8_conf].map do |conf|
     72            conf == '' ? nil : "-D#{conf}=1"
     73          end.compact.join(' ')
     74          bit = mode_32 ? '-m32 ' : ''
     75          _info = ''
     76          _info += mode_32 ? '32bit ' : '64bit '
     77          _info += float_conf['USE'] ? 'float ' : ''
     78          _info += int_conf['16'] ? 'int16 ' : ''
     79          _info += int_conf['64'] ? 'int64 ' : ''
     80          _info += boxing_conf['NAN'] ? 'nan ' : ''
     81          _info += boxing_conf['WORD'] ? 'word ' : ''
     82          _info += utf8_conf['UTF8'] ? 'utf8 ' : ''
     83          _info = _info.gsub(/ +/, ' ').strip.tr(' ', '_')
     84          configs << { '_info' => _info, 'CFLAGS' => "#{bit}#{env}", 'LDFLAGS' => bit.strip.to_s }
    8885        end
    8986      end
     
    111108        'image' => ci_docker_tag(compiler),
    112109        'variables' => hash,
    113         'script' => 'env; ./minirake --verbose all test'
     110        'script' => 'env; rake --verbose all test'
    114111      }
    115112    end
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/libmruby.rake

    r331 r439  
    11MRuby.each_target do
    2   file libfile("#{build_dir}/lib/libmruby") => libmruby.flatten do |t|
     2  file libmruby_static => libmruby_objs.flatten do |t|
    33    archiver.run t.name, t.prerequisites
    44  end
    55
    6   file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libfile("#{build_dir}/lib/libmruby")] do |t|
     6  file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libmruby_static] do |t|
     7    mkdir_p File.dirname t.name
    78    open(t.name, 'w') do |f|
    89      f.puts "MRUBY_CFLAGS = #{cc.all_flags}"
     
    1819      f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries)}"
    1920
    20       f.puts "MRUBY_LIBMRUBY_PATH = #{libfile("#{build_dir}/lib/libmruby")}"
     21      f.puts "MRUBY_LIBMRUBY_PATH = #{libmruby_static}"
    2122    end
    2223  end
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/mrbgems.rake

    r331 r439  
    66
    77    # loader all gems
    8     self.libmruby << objfile("#{build_dir}/mrbgems/gem_init")
     8    self.libmruby_objs << objfile("#{build_dir}/mrbgems/gem_init")
    99    file objfile("#{build_dir}/mrbgems/gem_init") => ["#{build_dir}/mrbgems/gem_init.c", "#{build_dir}/LEGAL"]
    1010    file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__] do |t|
    11       FileUtils.mkdir_p "#{build_dir}/mrbgems"
     11      mkdir_p "#{build_dir}/mrbgems"
    1212      open(t.name, 'w') do |f|
    1313        gem_func_gems = gems.select { |g| g.generate_functions }
     
    1919          s << "  GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb);\n"
    2020        end
    21         gem_final_calls = gem_func_gems.each_with_object('') do |g, s|
     21        gem_final_calls = gem_func_gems.reverse_each.with_object('') do |g, s|
    2222          s << "  GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb);\n"
    2323        end
     
    3535        f.puts %Q[]
    3636        f.write gem_func_decls
     37        unless gem_final_calls.empty?
    3738        f.puts %Q[]
    38         f.puts %Q[static void]
    39         f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
    40         f.write gem_final_calls
    41         f.puts %Q[}]
     39          f.puts %Q[static void]
     40          f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
     41          f.write gem_final_calls
     42          f.puts %Q[}]
     43        end
    4244        f.puts %Q[]
    4345        f.puts %Q[void]
     
    5254  # legal documents
    5355  file "#{build_dir}/LEGAL" => [MRUBY_CONFIG, __FILE__] do |t|
     56    mkdir_p File.dirname t.name
    5457    open(t.name, 'w+') do |f|
    5558     f.puts <<LEGAL
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/toolchains/android.rake

    r331 r439  
    88    /usr/local/opt/android-sdk/ndk-bundle
    99    /usr/local/opt/android-ndk
     10    ~/Android/Sdk/ndk-bundle
    1011    %LOCALAPPDATA%/Android/android-sdk/ndk-bundle
    1112    %LOCALAPPDATA%/Android/android-ndk
     13    %LOCALAPPDATA%/Android/Sdk/ndk/*
    1214    ~/Library/Android/sdk/ndk-bundle
    1315    ~/Library/Android/ndk
     
    3739Set ANDROID_PLATFORM environment variable or set :platform parameter
    3840        EOM
     41    end
     42  end
     43
     44  class SysrootNotReady < StandardError
     45    def message
     46      <<-EOM
     47Couldn't find standard header files
     48Please Move/Copy important file inside
     49  <NDK_HOME>/sysroot/usr/include/
     50to
     51  <NDK_HOME>/platforms/<ANDROID_VERSION>/<ARCH>/usr/include/
     52Higher NDK version will be use.
     53      EOM
    3954    end
    4055  end
     
    6782
    6883  def home_path
    69     @home_path ||= Pathname(
     84    @home_path ||= Pathname.new(
    7085      params[:ndk_home] ||
    7186      ENV['ANDROID_NDK_HOME'] ||
     
    7489        path.gsub! '\\', '/'
    7590        path.gsub! '~', Dir.home || '~'
     91        path.gsub!('*') do
     92          next nil unless path[-1] == "*"
     93          dirs = Dir.glob(path).collect do |d|
     94            m = d.match(/(\d+)\.(\d+)\.(\d+)$/)
     95            m ? [m[1], m[2], m[3]].collect { |v| v.to_i } : nil
     96          end
     97          dirs.compact!
     98          dirs.sort! do |before, after|
     99            f = 0
     100            if (f = (after.first <=> before.first)) != 0
     101              next f
     102            elsif (f = (after[1] <=> before[1])) != 0
     103              next f
     104            else
     105              next after.last <=> before.last
     106            end
     107          end
     108          dirs.empty? ? nil.to_s : dirs.first.join(".")
     109        end
    76110        File.directory?(path)
    77111      } || raise(AndroidNDKHomeNotFound)
     
    124158        Dir.glob(path.to_s){ |item|
    125159          next if File.file?(item)
    126           path = Pathname(item)
     160          path = Pathname.new(item)
    127161          break
    128162        }
     
    146180
    147181  def sysroot
    148     @sysroot ||= home_path.join('platforms', platform,
     182    return @sysroot if @sysroot
     183    sysroot_path = home_path.join('platforms', platform,
    149184        case arch
    150185        when /armeabi/    then 'arch-arm'
     
    156191        end
    157192      ).to_s
     193    if Dir.exist?(File.join(sysroot_path, "usr", "include"))
     194      return @sysroot = sysroot_path
     195    else
     196      raise(SysrootNotReady)
     197    end
    158198  end
    159199
     
    259299    flags = []
    260300
     301    case RUBY_PLATFORM
     302    when /mswin|mingw|win32/
     303      # Build for Android dont need window flag
     304      flags += %W(-U_WIN32 -U_WIN64)
     305    end
     306
    261307    flags += %W(-MMD -MP -D__android__ -DANDROID --sysroot="#{sysroot}")
    262308    flags += ctarget
     
    264310    when :gcc
    265311    when :clang
    266       flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}" -Wno-invalid-command-line-argument -Wno-unused-command-line-argument)
     312      flags += %W(-gcc-toolchain "#{gcc_toolchain_path}" -Wno-invalid-command-line-argument -Wno-unused-command-line-argument)
    267313    end
    268314    flags += %W(-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes)
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/toolchains/clang.rake

    r331 r439  
    11MRuby::Toolchain.new(:clang) do |conf, _params|
    2   toolchain :gcc
     2  toolchain :gcc, default_command: 'clang'
    33
    44  [conf.cc, conf.objc, conf.asm].each do |cc|
    5     cc.command = ENV['CC'] || 'clang'
     5    cc.flags << '-Wzero-length-array' unless ENV['CFLAGS']
    66  end
    7   conf.cxx.command = ENV['CXX'] || 'clang++'
    8   conf.linker.command = ENV['LD'] || 'clang'
     7  conf.cxx.flags << '-Wzero-length-array' unless ENV['CXXFLAGS'] || ENV['CFLAGS']
    98end
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/toolchains/emscripten.rake

    r321 r439  
    1 MRuby::Toolchain.new(:emscripten) do |conf|
    2   toolchain :gcc
     1MRuby::Toolchain.new(:emscripten) do |conf, _params|
     2  toolchain :gcc, default_command: 'emcc'
    33
    4   conf.cc do |cc|
    5     cc.command = "emcc"
    6     cc.flags.push(%w(-Wall -Werror-implicit-function-declaration -O0))
    7     cc.flags[0].delete_at(cc.flags[0].rindex("-Og"))
     4  [conf.cc, conf.objc, conf.asm].each do |cc|
     5    i = cc.flags[1][0].rindex("-Og")
     6    cc.flags[1][0][i] = "-O3" if i
    87  end
    98
    10   conf.cxx do |cxx|
    11     cxx.command = "emcc"
    12     cxx.flags.push(%w(-Wall -Werror-implicit-function-declaration -O0))
    13     cxx.flags[0].delete_at(cxx.flags[0].rindex("-Og"))
    14   end
    15 
    16   conf.linker.command = "emcc"
    179  conf.archiver.command = "emar"
    1810  conf.exts.executable = '.js'
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/toolchains/gcc.rake

    r331 r439  
    1 MRuby::Toolchain.new(:gcc) do |conf, _params|
    2   [conf.cc, conf.objc, conf.asm].each do |cc|
    3     cc.command = ENV['CC'] || 'gcc'
    4     cc.flags = [ENV['CFLAGS'] || %w(-g -std=gnu99 -Og -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings)]
    5     cc.defines = %w(DISABLE_GEMS)
    6     cc.option_include_path = '-I%s'
    7     cc.option_define = '-D%s'
    8     cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
    9     cc.cxx_compile_flag = '-x c++ -std=c++03'
    10     cc.cxx_exception_flag = '-fexceptions'
    11   end
     1MRuby::Toolchain.new(:gcc) do |conf, params|
     2  default_command = params[:default_command] || 'gcc'
     3  compiler_flags = %w(-g3 -Og -Wall -Wundef)
     4  c_mandatory_flags = %w(-std=gnu99)
     5  cxx_invalid_flags = %w(-Wdeclaration-after-statement -Werror-implicit-function-declaration)
    126
    13   [conf.cxx].each do |cxx|
    14     cxx.command = ENV['CXX'] || 'g++'
    15     cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(-g -Og -Wall -Werror-implicit-function-declaration)]
    16     cxx.defines = %w(DISABLE_GEMS)
    17     cxx.option_include_path = '-I%s'
    18     cxx.option_define = '-D%s'
    19     cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
    20     cxx.cxx_compile_flag = '-x c++ -std=c++03'
    21     cxx.cxx_exception_flag = '-fexceptions'
     7  [conf.cc, conf.objc, conf.asm, conf.cxx].each do |compiler|
     8    if compiler == conf.cxx
     9      compiler.command = ENV['CXX'] || default_command.sub(/cc|$/, '++')
     10      compiler.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || compiler_flags]
     11    else
     12      compiler.command = ENV['CC'] || default_command
     13      compiler.flags = [c_mandatory_flags, ENV['CFLAGS'] || [compiler_flags, cxx_invalid_flags, %w(-Wwrite-strings)]]
     14    end
     15    compiler.option_include_path = %q[-I"%s"]
     16    compiler.option_define = '-D%s'
     17    compiler.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
     18    compiler.cxx_compile_flag = '-x c++ -std=gnu++03'
     19    compiler.cxx_exception_flag = '-fexceptions'
     20    compiler.cxx_invalid_flags = c_mandatory_flags + cxx_invalid_flags
    2221  end
    2322
    2423  conf.linker do |linker|
    25     linker.command = ENV['LD'] || 'gcc'
     24    linker.command = ENV['LD'] || ENV['CXX'] || ENV['CC'] || default_command
    2625    linker.flags = [ENV['LDFLAGS'] || %w()]
    2726    linker.libraries = %w(m)
     
    2928    linker.option_library = '-l%s'
    3029    linker.option_library_path = '-L%s'
    31     linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
     30    linker.link_options = '%{flags} -o "%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
    3231  end
    3332
     
    5655    end
    5756  end
     57
     58  def conf.enable_sanitizer(*opts)
     59    fail 'sanitizer already set' if @sanitizer_list
     60
     61    @sanitizer_list = opts
     62    flg = "-fsanitize=#{opts.join ','}"
     63    [self.cc, self.cxx, self.linker].each{|cmd| cmd.flags << flg }
     64  end
    5865end
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/toolchains/openwrt.rake

    r331 r439  
    66    cc.flags = ENV['TARGET_CFLAGS']
    77    cc.include_paths = ["#{MRUBY_ROOT}/include"]
    8     cc.defines = %w(DISABLE_GEMS)
    9     cc.option_include_path = '-I%s'
     8    cc.option_include_path = %q[-I"%s"]
    109    cc.option_define = '-D%s'
    11     cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
     10    cc.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
    1211  end
    1312
     
    1615    cxx.flags = ENV['TARGET_CXXFLAGS']
    1716    cxx.include_paths = ["#{MRUBY_ROOT}/include"]
    18     cxx.defines = %w(DISABLE_GEMS)
    19     cxx.option_include_path = '-I%s'
     17    cxx.option_include_path = %q[-I"%s"]
    2018    cxx.option_define = '-D%s'
    21     cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
     19    cxx.compile_options = %q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
    2220   end
    2321
     
    2927    linker.option_library = '-l%s'
    3028    linker.option_library_path = '-L%s'
    31     linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
     29    linker.link_options = '%{flags} -o "%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
    3230  end
    3331
    3432  conf.archiver do |archiver|
    3533    archiver.command = ENV['TARGET_AR']
    36     archiver.archive_options = 'rs %{outfile} %{objs}'
     34    archiver.archive_options = 'rs "%{outfile}" %{objs}'
    3735  end
    3836end
  • EcnlProtoTool/trunk/mruby-2.1.1/tasks/toolchains/visualcpp.rake

    r331 r439  
    11MRuby::Toolchain.new(:visualcpp) do |conf, _params|
     2  conf.file_separator = '\\'
     3
    24  conf.cc do |cc|
    35    cc.command = ENV['CC'] || 'cl.exe'
    4     # C4013: implicit function declaration
    5     cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /utf-8 /D_CRT_SECURE_NO_WARNINGS)]
    6     cc.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING)
    7     cc.option_include_path = '/I%s'
     6    cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /utf-8 /W4 /GS /analyze- /Zc:wchar_t /Zi /O2 /Zc:inline /fp:precise /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /MD /EHsc /DWIN32 /DNDEBUG /D_CONSOLE /D_CRT_SECURE_NO_WARNINGS)]
     7    cc.flags << %w(/we4002 /we4003 /we4005 /we4007 /we4010 /we4013 /we4015 /we4020 /we4022 /we4024 /we4028 /we4029 /we4031 /we4033 /we4034 /we4042 /we4047 /we4048 /we4049 /we4056 /we4067 /we4074 /we4079 /we4083 /we4088 /we4089 /we4090 /we4091 /we4094 /we4096 /we4098 /we4099 /we4113 /we4133 /we4715 /we4716)
     8    cc.flags << %w(/wd4214 /wd4100 /wd4996)
     9    cc.flags << ["/Fd\"#{conf.build_dir.gsub('/', conf.file_separator)}\\vc142.pdb\""]
     10    cc.flags << ["/Fp\"%{outdir}\\%{outfilebase}.pch\""]
     11    cc.defines = %w(MRB_STACK_EXTEND_DOUBLING)
     12    cc.option_include_path = %q[/I"%s"]
    813    cc.option_define = '/D%s'
    9     cc.compile_options = "%{flags} /Fo%{outfile} %{infile}"
     14    cc.compile_options = %Q[%{flags} /Fo"%{outfile}" "%{infile}"]
    1015    cc.cxx_compile_flag = '/TP'
    1116    cc.cxx_exception_flag = '/EHs'
     
    1419  conf.cxx do |cxx|
    1520    cxx.command = ENV['CXX'] || 'cl.exe'
    16     cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHs /utf-8 /D_CRT_SECURE_NO_WARNINGS)]
    17     cxx.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING)
    18     cxx.option_include_path = '/I%s'
     21    cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /utf-8 /W4 /GS /analyze- /Zc:wchar_t /Zi /O2 /Zc:inline /fp:precise /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /MD /EHsc /DWIN32 /DNDEBUG /D_CONSOLE /D_CRT_SECURE_NO_WARNINGS)]
     22    cxx.flags << %w(/we4002 /we4003 /we4005 /we4007 /we4010 /we4013 /we4015 /we4020 /we4022 /we4024 /we4028 /we4029 /we4031 /we4033 /we4034 /we4042 /we4047 /we4048 /we4049 /we4056 /we4067 /we4074 /we4079 /we4083 /we4088 /we4089 /we4090 /we4091 /we4094 /we4096 /we4098 /we4099 /we4113 /we4133 /we4715 /we4716)
     23    cxx.flags << %w(/wd4214 /wd4100 /wd4996)
     24    cxx.flags << ["/Fd\"#{conf.build_dir.gsub('/', conf.file_separator)}\\vc142.pdb\""]
     25    cxx.flags << ["/Fp\"%{outdir}\\%{outfilebase}.pch\""]
     26    cxx.defines = %w(MRB_STACK_EXTEND_DOUBLING)
     27    cxx.option_include_path = %q[/I"%s"]
    1928    cxx.option_define = '/D%s'
    20     cxx.compile_options = "%{flags} /Fo%{outfile} %{infile}"
     29    cxx.compile_options = %Q[%{flags} /Fo"%{outfile}" "%{infile}"]
    2130    cxx.cxx_compile_flag = '/TP'
    2231    cxx.cxx_exception_flag = '/EHs'
     
    2534  conf.linker do |linker|
    2635    linker.command = ENV['LD'] || 'link.exe'
    27     linker.flags = [ENV['LDFLAGS'] || %w(/MANIFEST /NXCOMPAT /DYNAMICBASE /MACHINE:X86 /INCREMENTAL /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1)]
    28     linker.flags << "/PDB:\"#{conf.build_dir}\\vc140.pdb\""
    29     #linker.flags << "/PGD:\"%{outdir}\\%{outfilebase}.pgd\""
    30     linker.flags << "/ManifestFile:\"%{outdir}\\%{outfilebase}.exe.intermediate.manifest\""
     36    linker.flags = [ENV['LDFLAGS'] || %w(/MANIFEST /NXCOMPAT /DYNAMICBASE /DEBUG /OPT:REF /INCREMENTAL:NO /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1)]
     37    #linker.flags = [ENV['LDFLAGS'] || %w(/MANIFEST /LTCG:incremental /NXCOMPAT /DYNAMICBASE /DEBUG /OPT:REF /INCREMENTAL:NO /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1)]
     38    #linker.flags << ["/PGD:\"%{outdir}\\%{outfilebase}.pgd\""]
     39    linker.flags << ["/PDB:\"#{conf.build_dir.gsub('/', conf.file_separator)}\\vc142.pdb\""]
     40    linker.flags << ["/ManifestFile:\"%{outdir}\\%{outfilebase}.exe.intermediate.manifest\""]
    3141    linker.libraries = %w()
    3242    linker.library_paths = %w()
    3343    linker.option_library = '%s.lib'
    3444    linker.option_library_path = '/LIBPATH:%s'
    35     linker.link_options = "%{flags} /OUT:%{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
     45    linker.link_options = %Q[%{flags} /OUT:"%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}]
    3646  end
    3747
    3848  conf.archiver do |archiver|
    3949    archiver.command = ENV['AR'] || 'lib.exe'
    40     archiver.archive_options = '/nologo /OUT:%{outfile} %{objs}'
     50    archiver.archive_options = '/nologo /OUT:"%{outfile}" %{objs}'
    4151  end
    4252
    4353  conf.yacc do |yacc|
    4454    yacc.command = ENV['YACC'] || 'bison.exe'
    45     yacc.compile_options = '-o %{outfile} %{infile}'
     55    yacc.compile_options = %q[-o "%{outfile}" "%{infile}"]
    4656  end
    4757
    4858  conf.gperf do |gperf|
    4959    gperf.command = 'gperf.exe'
    50     gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
     60    gperf.compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
    5161  end
    5262
     
    5767  end
    5868
    59   conf.file_separator = '\\'
    60 
    61   if require 'open3'
    62     Open3.popen3 conf.cc.command do |_, _, e, _|
    63       if /Version (\d{2})\.\d{2}\.\d{5}/ =~ e.gets && $1.to_i <= 17
    64         m = "# VS2010/2012 support will be dropped after the next release! #"
    65         h = "#" * m.length
    66         puts h, m, h
    67       end
    68     end
    69   end
    70 
    7169end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/assert.rb

    r331 r439  
     1$undefined = Object.new
    12$ok_test = 0
    23$ko_test = 0
    34$kill_test = 0
     5$warning_test = 0
     6$skip_test = 0
    47$asserts  = []
    58$test_start = Time.now if Object.const_defined?(:Time)
    69
    7 # Implementation of print due to the reason that there might be no print
    8 def t_print(*args)
    9   i = 0
    10   len = args.size
    11   while i < len
    12     str = args[i].to_s
    13     __t_printstr__ str rescue print str
    14     i += 1
     10# For bintest on Ruby
     11unless RUBY_ENGINE == "mruby"
     12  def t_print(*args)
     13    print(*args)
     14    $stdout.flush
     15    nil
     16  end
     17
     18  def _str_match?(pattern, str)
     19    File.fnmatch?(pattern, str, File::FNM_EXTGLOB|File::FNM_DOTMATCH)
     20  end
     21end
     22
     23class Array
     24  def _assertion_join
     25    join("-")
     26  end
     27end
     28
     29class String
     30  def _assertion_indent(indent)
     31    indent = indent.to_s
     32    off = 0
     33    str = self
     34    while nl = index("\n", off)
     35      nl += 1
     36      nl += 1 while slice(nl) == "\n"
     37      break if nl >= size
     38      str = indent.dup if off == 0
     39      str += slice(off, nl - off) + indent
     40      off = nl
     41    end
     42
     43    if off == 0
     44      str = indent + self
     45    else
     46      str += slice(off..-1)
     47    end
     48
     49    str
    1550  end
    1651end
     
    2055def assertion_string(err, str, iso=nil, e=nil, bt=nil)
    2156  msg = "#{err}#{str}"
    22   msg += " [#{iso}]" if iso && iso != ''
    23   msg += " => #{e.message}" if e
    24   msg += " (mrbgems: #{GEMNAME})" if Object.const_defined?(:GEMNAME)
    25   if $mrbtest_assert && $mrbtest_assert.size > 0
    26     $mrbtest_assert.each do |idx, str, diff|
    27       msg += "\n - Assertion[#{idx}] Failed: #{str}\n#{diff}"
    28     end
    29   end
    30   msg += "\nbacktrace:\n\t#{bt.join("\n\t")}" if bt
     57  msg += " [#{iso}]" if iso && !iso.empty?
     58  msg += " => #{e}" if e && !e.to_s.empty?
     59  msg += " (#{GEMNAME == 'mruby-test' ? 'core' : "mrbgems: #{GEMNAME}"})"
     60  if $mrbtest_assert
     61    $mrbtest_assert.each do |idx, assert_msg, diff|
     62      msg += "\n - Assertion[#{idx}]"
     63      msg += " #{assert_msg}." if assert_msg && !assert_msg.empty?
     64      msg += "\n#{diff}" if diff && !diff.empty?
     65    end
     66  end
     67  msg += "\nbacktrace:\n        #{bt.join("\n        ")}" if bt
    3168  msg
    3269end
     
    4077#       which will be tested by this
    4178#       assertion
    42 def assert(str = 'Assertion failed', iso = '')
     79def assert(str = 'assert', iso = '')
    4380  t_print(str, (iso != '' ? " [#{iso}]" : ''), ' : ') if $mrbtest_verbose
    4481  begin
     82    $mrbtest_child_noassert ||= [0]
     83    $mrbtest_child_noassert << 0
     84    parent_asserts = $asserts
     85    $asserts = []
     86    parent_mrbtest_assert = $mrbtest_assert
    4587    $mrbtest_assert = []
    46     $mrbtest_assert_idx = 0
     88
     89    if $mrbtest_assert_idx && !$mrbtest_assert_idx.empty?
     90      $mrbtest_assert_idx[-1] += 1
     91      $mrbtest_assert_idx << 0
     92    else
     93      $mrbtest_assert_idx = [0]
     94      class << $mrbtest_assert_idx
     95        alias to_s _assertion_join
     96      end
     97    end
     98
    4799    yield
    48     if($mrbtest_assert.size > 0)
    49       $asserts.push(assertion_string('Fail: ', str, iso, nil))
    50       $ko_test += 1
    51       t_print('F')
     100    if $mrbtest_assert.size > 0
     101      if $mrbtest_assert.size == $mrbtest_child_noassert[-1]
     102        $asserts.push(assertion_string('Skip: ', str, iso))
     103        $mrbtest_child_noassert[-2] += 1
     104        $skip_test += 1
     105        t_print('?')
     106      else
     107        $asserts.push(assertion_string('Fail: ', str, iso))
     108        $ko_test += 1
     109        t_print('F')
     110      end
     111    elsif $mrbtest_assert_idx[-1] == 0
     112      $asserts.push(assertion_string('Warn: ', str, iso, 'no assertion'))
     113      $warning_test += 1
     114      t_print('W')
    52115    else
    53116      $ok_test += 1
    54117      t_print('.')
    55118    end
     119  rescue MRubyTestSkip => e
     120    $asserts.push(assertion_string('Skip: ', str, iso, e))
     121    $skip_test += 1
     122    $mrbtest_child_noassert[-2] += 1
     123    t_print('?')
    56124  rescue Exception => e
    57125    bt = e.backtrace if $mrbtest_verbose
    58     if e.class.to_s == 'MRubyTestSkip'
    59       $asserts.push "Skip: #{str} #{iso} #{e.cause}"
    60       t_print('?')
     126    $asserts.push(assertion_string("#{e.class}: ", str, iso, e, bt))
     127    $kill_test += 1
     128    t_print('X')
     129  ensure
     130    if $mrbtest_assert_idx.size > 1
     131      $asserts.each do |mesg|
     132        idx = $mrbtest_assert_idx[0..-2]._assertion_join
     133        mesg = mesg._assertion_indent("    ")
     134
     135        # Give `mesg` as a `diff` argument to avoid adding extra periods.
     136        parent_mrbtest_assert << [idx, nil, mesg]
     137      end
    61138    else
    62       $asserts.push(assertion_string("#{e.class}: ", str, iso, e, bt))
    63       $kill_test += 1
    64       t_print('X')
    65   end
    66   ensure
    67     $mrbtest_assert = nil
     139      parent_asserts.concat $asserts
     140    end
     141    $asserts = parent_asserts
     142
     143    $mrbtest_assert = parent_mrbtest_assert
     144    $mrbtest_assert_idx.pop
     145    $mrbtest_assert_idx = nil if $mrbtest_assert_idx.empty?
     146    $mrbtest_child_noassert.pop
     147
     148    nil
    68149  end
    69150  t_print("\n") if $mrbtest_verbose
     
    71152
    72153def assertion_diff(exp, act)
    73   "    Expected: #{exp.inspect}\n" +
     154  "    Expected: #{exp.inspect}\n" \
    74155  "      Actual: #{act.inspect}"
    75156end
    76157
    77 def assert_true(ret, msg = nil, diff = nil)
    78   if $mrbtest_assert
    79     $mrbtest_assert_idx += 1
    80     unless ret
    81       msg = "Expected #{ret.inspect} to be true" unless msg
    82       diff = assertion_diff(true, ret)  unless diff
    83       $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
    84     end
    85   end
    86   ret
    87 end
    88 
    89 def assert_false(ret, msg = nil, diff = nil)
    90   if $mrbtest_assert
    91     $mrbtest_assert_idx += 1
    92     if ret
    93       msg = "Expected #{ret.inspect} to be false" unless msg
    94       diff = assertion_diff(false, ret) unless diff
    95 
    96       $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
    97     end
    98   end
    99   !ret
    100 end
    101 
    102 def assert_equal(arg1, arg2 = nil, arg3 = nil)
    103   if block_given?
    104     exp, act, msg = arg1, yield, arg2
    105   else
    106     exp, act, msg = arg1, arg2, arg3
    107   end
    108 
    109   msg = "Expected to be equal" unless msg
    110   diff = assertion_diff(exp, act)
    111   assert_true(exp == act, msg, diff)
    112 end
    113 
    114 def assert_not_equal(arg1, arg2 = nil, arg3 = nil)
    115   if block_given?
    116     exp, act, msg = arg1, yield, arg2
    117   else
    118     exp, act, msg = arg1, arg2, arg3
    119   end
    120 
    121   msg = "Expected to be not equal" unless msg
    122   diff = assertion_diff(exp, act)
    123   assert_false(exp == act, msg, diff)
     158def assert_true(obj, msg = nil, diff = nil)
     159  if $mrbtest_assert_idx && $mrbtest_assert_idx.size > 0
     160    $mrbtest_assert_idx[-1] += 1
     161    unless obj == true
     162      diff ||= "    Expected #{obj.inspect} to be true."
     163      $mrbtest_assert.push([$mrbtest_assert_idx.to_s, msg, diff])
     164    end
     165  end
     166  obj
     167end
     168
     169def assert_false(obj, msg = nil, diff = nil)
     170  unless obj == false
     171    diff ||= "    Expected #{obj.inspect} to be false."
     172  end
     173  assert_true(!obj, msg, diff)
     174end
     175
     176def assert_equal(exp, act_or_msg = nil, msg = nil, &block)
     177  ret, exp, act, msg = _eval_assertion(:==, exp, act_or_msg, msg, block)
     178  unless ret
     179    diff = assertion_diff(exp, act)
     180  end
     181  assert_true(ret, msg, diff)
     182end
     183
     184def assert_not_equal(exp, act_or_msg = nil, msg = nil, &block)
     185  ret, exp, act, msg = _eval_assertion(:==, exp, act_or_msg, msg, block)
     186  if ret
     187    diff = "    Expected #{act.inspect} to not be equal to #{exp.inspect}."
     188  end
     189  assert_true(!ret, msg, diff)
     190end
     191
     192def assert_same(*args); _assert_same(true, *args) end
     193def assert_not_same(*args); _assert_same(false, *args) end
     194def _assert_same(affirmed, exp, act, msg = nil)
     195  unless ret = exp.equal?(act) == affirmed
     196    exp_str, act_str = [exp, act].map do |o|
     197      "#{o.inspect} (class=#{o.class}, oid=#{o.__id__})"
     198    end
     199    diff = "    Expected #{act_str} to #{'not ' unless affirmed}be the same as #{exp_str}."
     200  end
     201  assert_true(ret, msg, diff)
    124202end
    125203
    126204def assert_nil(obj, msg = nil)
    127   msg = "Expected #{obj.inspect} to be nil" unless msg
    128   diff = assertion_diff(nil, obj)
    129   assert_true(obj.nil?, msg, diff)
    130 end
    131 
    132 def assert_include(collection, obj, msg = nil)
    133   msg = "Expected #{collection.inspect} to include #{obj.inspect}" unless msg
    134   diff = "    Collection: #{collection.inspect}\n" +
    135          "        Object: #{obj.inspect}"
    136   assert_true(collection.include?(obj), msg, diff)
    137 end
    138 
    139 def assert_not_include(collection, obj, msg = nil)
    140   msg = "Expected #{collection.inspect} to not include #{obj.inspect}" unless msg
    141   diff = "    Collection: #{collection.inspect}\n" +
    142          "        Object: #{obj.inspect}"
    143   assert_false(collection.include?(obj), msg, diff)
    144 end
    145 
    146 def assert_raise(*exp)
    147   ret = true
    148   if $mrbtest_assert
    149     $mrbtest_assert_idx += 1
    150     msg = exp.last.class == String ? exp.pop : nil
    151     msg = msg.to_s + " : " if msg
    152     should_raise = false
    153     begin
    154       yield
    155       should_raise = true
    156     rescue Exception => e
    157       msg = "#{msg}#{exp.inspect} exception expected, not"
    158       diff = "      Class: <#{e.class}>\n" +
    159              "    Message: #{e.message}"
    160       if not exp.any?{|ex| ex.instance_of?(Module) ? e.kind_of?(ex) : ex == e.class }
    161         $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
    162         ret = false
    163       end
    164     end
    165 
    166     exp = exp.first if exp.first
    167     if should_raise
    168       msg = "#{msg}#{exp.inspect} expected but nothing was raised."
    169       $mrbtest_assert.push([$mrbtest_assert_idx, msg, nil])
    170       ret = false
    171     end
    172   end
    173   ret
    174 end
    175 
    176 def assert_nothing_raised(*exp)
    177   ret = true
    178   if $mrbtest_assert
    179     $mrbtest_assert_idx += 1
    180     msg = exp.last.class == String ? exp.pop : ""
    181     begin
    182       yield
    183     rescue Exception => e
    184       msg = "#{msg} exception raised."
    185       diff = "      Class: <#{e.class}>\n" +
    186              "    Message: #{e.message}"
    187       $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
    188       ret = false
    189     end
    190   end
    191   ret
     205  unless ret = obj.nil?
     206    diff = "    Expected #{obj.inspect} to be nil."
     207  end
     208  assert_true(ret, msg, diff)
     209end
     210
     211def assert_not_nil(obj, msg = nil)
     212  if ret = obj.nil?
     213    diff = "    Expected #{obj.inspect} to not be nil."
     214  end
     215  assert_false(ret, msg, diff)
     216end
     217
     218def assert_include(*args); _assert_include(true, *args) end
     219def assert_not_include(*args); _assert_include(false, *args) end
     220def _assert_include(affirmed, collection, obj, msg = nil)
     221  unless ret = collection.include?(obj) == affirmed
     222    diff = "    Expected #{collection.inspect} to #{'not ' unless affirmed}include #{obj.inspect}."
     223  end
     224  assert_true(ret, msg, diff)
     225end
     226
     227def assert_predicate(*args); _assert_predicate(true, *args) end
     228def assert_not_predicate(*args); _assert_predicate(false, *args) end
     229def _assert_predicate(affirmed, obj, op, msg = nil)
     230  unless ret = obj.__send__(op) == affirmed
     231    diff = "    Expected #{obj.inspect} to #{'not ' unless affirmed}be #{op}."
     232  end
     233  assert_true(ret, msg, diff)
     234end
     235
     236def assert_operator(*args); _assert_operator(true, *args) end
     237def assert_not_operator(*args); _assert_operator(false, *args) end
     238def _assert_operator(affirmed, obj1, op, obj2 = $undefined, msg = nil)
     239  return _assert_predicate(affirmed, obj1, op, msg) if $undefined.equal?(obj2)
     240  unless ret = obj1.__send__(op, obj2) == affirmed
     241    diff = "    Expected #{obj1.inspect} to #{'not ' unless affirmed}be #{op} #{obj2.inspect}."
     242  end
     243  assert_true(ret, msg, diff)
     244end
     245
     246##
     247# Fail unless +str+ matches against +pattern+.
     248#
     249# +pattern+ is interpreted as pattern for File.fnmatch?. It may contain the
     250# following metacharacters:
     251#
     252# <code>*</code> ::
     253#   Matches any string.
     254#
     255# <code>?</code> ::
     256#   Matches any one character.
     257#
     258# <code>[_SET_]</code>, <code>[^_SET_]</code> (<code>[!_SET_]</code>) ::
     259#   Matches any one character in _SET_.  Behaves like character sets in
     260#   Regexp, including set negation (<code>[^a-z]</code>).
     261#
     262# <code>{_A_,_B_}</code> ::
     263#   Matches pattern _A_ or pattern _B_.
     264#
     265# <code> \ </code> ::
     266#   Escapes the next character.
     267def assert_match(*args); _assert_match(true, *args) end
     268def assert_not_match(*args); _assert_match(false, *args) end
     269def _assert_match(affirmed, pattern, str, msg = nil)
     270  unless ret = _str_match?(pattern, str) == affirmed
     271    diff = "    Expected #{pattern.inspect} to #{'not ' unless affirmed}match #{str.inspect}."
     272  end
     273  assert_true(ret, msg, diff)
    192274end
    193275
     
    195277# Fails unless +obj+ is a kind of +cls+.
    196278def assert_kind_of(cls, obj, msg = nil)
    197   msg = "Expected #{obj.inspect} to be a kind of #{cls}, not #{obj.class}" unless msg
    198   diff = assertion_diff(cls, obj.class)
    199   assert_true(obj.kind_of?(cls), msg, diff)
     279  unless ret = obj.kind_of?(cls)
     280    diff = "    Expected #{obj.inspect} to be a kind of #{cls}, not #{obj.class}."
     281  end
     282  assert_true(ret, msg, diff)
    200283end
    201284
     
    203286# Fails unless +exp+ is equal to +act+ in terms of a Float
    204287def assert_float(exp, act, msg = nil)
    205   msg = "Float #{exp} expected to be equal to float #{act}" unless msg
    206   diff = assertion_diff(exp, act)
    207   assert_true check_float(exp, act), msg, diff
     288  e, a = exp.to_f, act.to_f
     289  if e.finite? && a.finite? && (n = (e - a).abs) > Mrbtest::FLOAT_TOLERANCE
     290    flunk(msg, "    Expected |#{exp} - #{act}| (#{n}) to be <= #{Mrbtest::FLOAT_TOLERANCE}.")
     291  elsif (e.infinite? || a.infinite?) && e != a ||
     292     e.nan? && !a.nan? || !e.nan? && a.nan?
     293    flunk(msg, "    Expected #{act} to be #{exp}.")
     294  else
     295    pass
     296  end
     297end
     298
     299def assert_raise(*exc)
     300  msg = (exc.last.is_a? String) ? exc.pop : nil
     301  exc = exc.empty? ? StandardError : exc.size == 1 ? exc[0] : exc
     302  begin
     303    yield
     304  rescue *exc => e
     305    pass
     306    e
     307  rescue Exception => e
     308    diff = "    #{exc} exception expected, not\n" \
     309           "    Class: <#{e.class}>\n" \
     310           "    Message: <#{e}>"
     311    flunk(msg, diff)
     312  else
     313    diff = "    #{exc} expected but nothing was raised."
     314    flunk(msg, diff)
     315  end
     316end
     317
     318def assert_nothing_raised(msg = nil)
     319  begin
     320    yield
     321  rescue Exception => e
     322    diff = "    Exception raised:\n" \
     323           "    Class: <#{e.class}>\n" \
     324           "    Message: <#{e}>"
     325    flunk(msg, diff)
     326  else
     327    pass
     328  end
     329end
     330
     331def assert_raise_with_message(*args, &block)
     332  _assert_raise_with_message(:plain, *args, &block)
     333end
     334def assert_raise_with_message_pattern(*args, &block)
     335  _assert_raise_with_message(:pattern, *args, &block)
     336end
     337def _assert_raise_with_message(type, exc, exp_msg, msg = nil, &block)
     338  e = msg ? assert_raise(exc, msg, &block) : assert_raise(exc, &block)
     339  e ? ($mrbtest_assert_idx[-1]-=1) : (return e)
     340
     341  err_msg = e.message
     342  unless ret = type == :pattern ? _str_match?(exp_msg, err_msg) : exp_msg == err_msg
     343    diff = "    Expected Exception(#{exc}) was raised, but the message doesn't match.\n"
     344    if type == :pattern
     345      diff += "    Expected #{exp_msg.inspect} to match #{err_msg.inspect}."
     346    else
     347      diff += assertion_diff(exp_msg, err_msg)
     348    end
     349  end
     350  assert_true(ret, msg, diff)
     351end
     352
     353def pass
     354  assert_true(true)
     355end
     356
     357def flunk(msg = "Epic Fail!", diff = "")
     358  assert_true(false, msg, diff)
    208359end
    209360
     
    211362# Report the test result and print all assertions
    212363# which were reported broken.
    213 def report()
     364def report
    214365  t_print("\n")
    215366
    216367  $asserts.each do |msg|
    217     t_print "#{msg}\n"
    218   end
    219 
    220   $total_test = $ok_test+$ko_test+$kill_test
    221   t_print("Total: #{$total_test}\n")
    222 
    223   t_print("   OK: #{$ok_test}\n")
    224   t_print("   KO: #{$ko_test}\n")
    225   t_print("Crash: #{$kill_test}\n")
     368    t_print("#{msg}\n")
     369  end
     370
     371  $total_test = $ok_test + $ko_test + $kill_test + $warning_test + $skip_test
     372  t_print("  Total: #{$total_test}\n")
     373
     374  t_print("     OK: #{$ok_test}\n")
     375  t_print("     KO: #{$ko_test}\n")
     376  t_print("  Crash: #{$kill_test}\n")
     377  t_print("Warning: #{$warning_test}\n")
     378  t_print("   Skip: #{$skip_test}\n")
    226379
    227380  if Object.const_defined?(:Time)
    228381    t_time = Time.now - $test_start
    229     t_print(" Time: #{t_time.round(2)} seconds\n")
    230   end
    231 end
    232 
    233 ##
    234 # Performs fuzzy check for equality on methods returning floats
    235 def check_float(a, b)
    236   tolerance = Mrbtest::FLOAT_TOLERANCE
    237   a = a.to_f
    238   b = b.to_f
    239   if a.finite? and b.finite?
    240     (a-b).abs < tolerance
     382    t_print("   Time: #{t_time.round(2)} seconds\n")
     383  end
     384
     385  $ko_test == 0 && $kill_test == 0
     386end
     387
     388def _eval_assertion(meth, exp, act_or_msg, msg, block)
     389  if block
     390    exp, act, msg = exp, block.call, act_or_msg
    241391  else
    242     true
    243   end
     392    exp, act, msg = exp, act_or_msg, msg
     393  end
     394  return exp.__send__(meth, act), exp, act, msg
    244395end
    245396
    246397##
    247398# Skip the test
    248 class MRubyTestSkip < NotImplementedError
    249   attr_accessor :cause
    250   def initialize(cause)
    251     @cause = cause
    252   end
    253 end
     399class MRubyTestSkip < NotImplementedError; end
    254400
    255401def skip(cause = "")
  • EcnlProtoTool/trunk/mruby-2.1.1/test/bintest.rb

    r331 r439  
    11$:.unshift File.dirname(File.dirname(File.expand_path(__FILE__)))
    22require 'test/assert.rb'
     3
     4GEMNAME = ""
    35
    46def cmd(s)
     
    2022end
    2123
     24print "bintest - Command Binary Test\n\n"
     25
    2226ARGV.each do |gem|
     27  case gem
     28  when '-v'; $mrbtest_verbose = true
     29  end
     30
    2331  case RbConfig::CONFIG['host_os']
    2432  when /mswin(?!ce)|mingw|bccwin/
     
    2735
    2836  Dir["#{gem}/bintest/**/*.rb"].each do |file|
     37    GEMNAME.replace(File.basename(gem))
    2938    load file
    3039  end
    3140end
    3241
    33 load 'test/report.rb'
     42exit report
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/array.rb

    r331 r439  
    5656
    5757  a = [ "a", "b", "c", "d", "e" ]
    58   assert_equal("b", a[1.1])
    5958  assert_equal(["b", "c"], a[1,2])
    6059  assert_equal(["b", "c", "d"], a[1..-2])
     60  skip unless Object.const_defined?(:Float)
     61  assert_equal("b", a[1.1])
    6162end
    6263
     
    238239  assert_equal([1,2], a)
    239240  assert_equal(3, b)
     241
     242  assert_raise(FrozenError) { [].freeze.pop }
    240243end
    241244
     
    285288  assert_equal([2,3], a)
    286289  assert_equal(1, b)
     290
     291  assert_raise(FrozenError) { [].freeze.shift }
    287292end
    288293
     
    294299
    295300assert('Array#slice', '15.2.12.5.29') do
    296   a = "12345".slice(1, 3)
    297   b = a.slice(0)
    298 
    299   assert_equal("2:", "#{b}:")
    300   assert_equal(2, [1,2,3].[](1))
     301  a = [*(1..100)]
     302  b = a.dup
     303
     304  assert_equal(1, a.slice(0))
     305  assert_equal(100, a.slice(99))
     306  assert_nil(a.slice(100))
     307  assert_equal(100, a.slice(-1))
     308  assert_equal(99,  a.slice(-2))
     309  assert_equal(1,   a.slice(-100))
     310  assert_nil(a.slice(-101))
     311  assert_equal([1],   a.slice(0,1))
     312  assert_equal([100], a.slice(99,1))
     313  assert_equal([],    a.slice(100,1))
     314  assert_equal([100], a.slice(99,100))
     315  assert_equal([100], a.slice(-1,1))
     316  assert_equal([99],  a.slice(-2,1))
     317  assert_equal([10, 11, 12], a.slice(9, 3))
     318  assert_equal([10, 11, 12], a.slice(-91, 3))
     319  assert_nil(a.slice(-101, 2))
     320  assert_equal([1],   a.slice(0..0))
     321  assert_equal([100], a.slice(99..99))
     322  assert_equal([],    a.slice(100..100))
     323  assert_equal([100], a.slice(99..200))
     324  assert_equal([100], a.slice(-1..-1))
     325  assert_equal([99],  a.slice(-2..-2))
     326  assert_equal([10, 11, 12], a.slice(9..11))
     327  assert_equal([10, 11, 12], a.slice(-91..-89))
     328  assert_equal([10, 11, 12], a.slice(-91..-89))
     329  assert_nil(a.slice(-101..-1))
     330  assert_nil(a.slice(10, -3))
     331  assert_equal([], a.slice(10..7))
     332  assert_equal(b, a)
    301333end
    302334
     
    315347assert('Array#to_s', '15.2.12.5.31 / 15.2.12.5.32') do
    316348  a = [2, 3,   4, 5]
     349  a[4] = a
    317350  r1 = a.to_s
    318351  r2 = a.inspect
    319352
    320353  assert_equal(r2, r1)
    321   assert_equal("[2, 3, 4, 5]", r1)
     354  assert_equal("[2, 3, 4, 5, [...]]", r1)
    322355end
    323356
     
    356389
    357390# Not ISO specified
    358 
    359 assert("Array (Shared Array Corruption)") do
    360   a = [ "a", "b", "c", "d", "e", "f" ]
    361   b = a.slice(1, 3)
    362   a.clear
    363   b.clear
    364 end
    365391
    366392assert("Array (Longish inline array)") do
     
    383409end
    384410
     411assert('Array#sort!') do
     412  a = [3, 2, 1]
     413  assert_equal a, a.sort!      # sort! returns self.
     414  assert_equal [1, 2, 3], a    # it is sorted.
     415end
     416
    385417assert('Array#freeze') do
    386418  a = [].freeze
    387   assert_raise(RuntimeError) do
     419  assert_raise(FrozenError) do
    388420    a[0] = 1
    389421  end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/bs_block.rb

    r321 r439  
    337337assert('BS Block 28') do
    338338  assert_equal(10) do
    339     3.times{|bl|
     339    3.times{
    340340      break 10
    341341    }
     
    409409
    410410assert('BS Block [ruby-core:14395]') do
    411   class Controller
    412     def respond_to(&block)
    413       responder = Responder.new
    414       block.call(responder)
    415       responder.respond
    416     end
    417     def test_for_bug
    418       respond_to{|format|
    419         format.js{
    420           "in test"
    421           render{|obj|
    422             obj
     411  assert_nothing_raised do
     412    class Controller
     413      def respond_to(&block)
     414        responder = Responder.new
     415        block.call(responder)
     416        responder.respond
     417      end
     418      def test_for_bug
     419        respond_to{|format|
     420          format.js{
     421            "in test"
     422            render{|obj|
     423              obj
     424            }
    423425          }
    424426        }
    425       }
    426     end
    427     def render(&block)
    428       "in render"
    429     end
    430   end
    431 
    432   class Responder
    433     def method_missing(symbol, &block)
    434       "enter method_missing"
    435       @response = Proc.new{
    436         'in method missing'
    437         block.call
    438       }
    439       "leave method_missing"
    440     end
    441     def respond
    442       @response.call
    443     end
    444   end
    445   t = Controller.new
    446   assert_true t.test_for_bug
     427      end
     428      def render(&block)
     429        "in render"
     430      end
     431    end
     432    class Responder
     433      def method_missing(symbol, &block)
     434        "enter method_missing"
     435        @response = Proc.new{
     436          'in method missing'
     437          block.call
     438        }
     439        "leave method_missing"
     440      end
     441      def respond
     442        @response.call
     443      end
     444    end
     445    t = Controller.new
     446    t.test_for_bug
     447  end
    447448end
    448449
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/class.rb

    r331 r439  
    3737assert('Class#new', '15.2.3.3.3') do
    3838  assert_raise(TypeError, 'Singleton should raise TypeError') do
    39     "a".singleton_class.new
     39    (class <<"a"; self; end).new
    4040  end
    4141
     
    237237end
    238238
     239assert('class to return nil if body is empty') do
     240  assert_nil(class C end)
     241  assert_nil(class << self; end)
     242end
     243
    239244assert('raise when superclass is not a class') do
    240245  module FirstModule; end
     
    294299  end
    295300
    296   assert_false baz.singleton_methods.include? :run_foo_mod
    297   assert_false baz.singleton_methods.include? :run_baz
    298 
    299   assert_raise(NoMethodError, 'should raise NoMethodError') do
    300     baz.run_foo_mod
    301   end
    302   assert_raise(NoMethodError, 'should raise NoMethodError') do
    303     baz.run_baz
    304   end
     301  assert_equal :run_baz, baz
    305302
    306303  assert_raise(NoMethodError, 'should raise NoMethodError') do
     
    319316  end
    320317
    321   assert_true baz.singleton_methods.include? :run_baz
    322   assert_true baz.singleton_methods.include? :run_foo_mod
     318  assert_true baz.respond_to? :run_baz
     319  assert_true baz.respond_to? :run_foo_mod
    323320  assert_equal 100, baz.run_foo_mod
    324321  assert_equal 300, baz.run_baz
     
    359356      end
    360357    end
    361   end
     358  end if Object.const_defined?(:Float)
     359
     360  o = Object.new
     361  sc = class << o; self end
     362  o.freeze
     363  assert_predicate(sc, :frozen?)
     364
     365  assert_predicate(class << Object.new.freeze; self end, :frozen?)
    362366end
    363367
     
    369373  end
    370374
    371   Foo.clone.new.func
     375  assert_true(Foo.clone.new.func)
    372376end
    373377
     
    437441end
    438442
     443assert('class variable for frozen class/module') do
     444  module CVarForFrozenModule
     445    freeze
     446    assert_raise(FrozenError) { @@cv = 1 }
     447  end
     448
     449  class CVarForFrozenClassA
     450    @@a = nil
     451    freeze
     452  end
     453  class CVarForFrozenClassB < CVarForFrozenClassA
     454    def a=(v)
     455      @@a = v
     456    end
     457  end
     458  b = CVarForFrozenClassB.new
     459  assert_raise(FrozenError) { b.a = 1 }
     460end
     461
    439462assert('class with non-class/module outer raises TypeError') do
    440463  assert_raise(TypeError) { class 0::C1; end }
    441464  assert_raise(TypeError) { class []::C2; end }
    442465end
    443 
    444 assert("remove_method doesn't segfault if the passed in argument isn't a symbol") do
    445   klass = Class.new
    446   assert_raise(TypeError) { klass.remove_method nil }
    447   assert_raise(TypeError) { klass.remove_method 123 }
    448   assert_raise(TypeError) { klass.remove_method 1.23 }
    449   assert_raise(NameError) { klass.remove_method "hello" }
    450   assert_raise(TypeError) { klass.remove_method Class.new }
    451 end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/codegen.rb

    r331 r439  
    7474  assert_equal [2], a
    7575end
     76
     77assert('register window of calls (#3783)') do
     78  # NODE_FOR
     79  assert_nothing_raised do
     80    for i in []; end
     81  end
     82
     83  # NODE_SYMBOLS
     84  assert_nothing_raised do
     85    %i(sym)
     86  end
     87
     88  # NODE_SCALL
     89  assert_nothing_raised do
     90    Object.new&.__id__
     91  end
     92
     93  # NODE_RESCUE with splat
     94  assert_nothing_raised do
     95    begin
     96      raise
     97    rescue *[Exception]
     98    end
     99  end
     100
     101  # NODE_CASE
     102  assert_nothing_raised do
     103    case 1
     104    when nil
     105    end
     106  end
     107
     108  # NODE_CASE with splat
     109  assert_nothing_raised do
     110    case 1
     111    when *nil
     112    end
     113  end
     114
     115  # NODE_HASH
     116  assert_nothing_raised do
     117    {}.merge(
     118        0=>0,     1=>1,     2=>2,     3=>3,     4=>4,     5=>5,     6=>6,     7=>7,     8=>8,     9=>9,
     119       10=>10,   11=>11,   12=>12,   13=>13,   14=>14,   15=>15,   16=>16,   17=>17,   18=>18,   19=>19,
     120       20=>20,   21=>21,   22=>22,   23=>23,   24=>24,   25=>25,   26=>26,   27=>27,   28=>28,   29=>29,
     121       30=>30,   31=>31,   32=>32,   33=>33,   34=>34,   35=>35,   36=>36,   37=>37,   38=>38,   39=>39,
     122       40=>40,   41=>41,   42=>42,   43=>43,   44=>44,   45=>45,   46=>46,   47=>47,   48=>48,   49=>49,
     123       50=>50,   51=>51,   52=>52,   53=>53,   54=>54,   55=>55,   56=>56,   57=>57,   58=>58,   59=>59,
     124       60=>60,   61=>61,   62=>62,   63=>63,   64=>64,   65=>65,   66=>66,   67=>67,   68=>68,   69=>69,
     125       70=>70,   71=>71,   72=>72,   73=>73,   74=>74,   75=>75,   76=>76,   77=>77,   78=>78,   79=>79,
     126       80=>80,   81=>81,   82=>82,   83=>83,   84=>84,   85=>85,   86=>86,   87=>87,   88=>88,   89=>89,
     127       90=>90,   91=>91,   92=>92,   93=>93,   94=>94,   95=>95,   96=>96,   97=>97,   98=>98,   99=>99,
     128      100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109,
     129      110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119,
     130      120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126)
     131  end
     132
     133  # NODE_OP_ASGN
     134  o = Object.new
     135  class << o
     136    attr_accessor :a
     137  end
     138
     139  o.a = 1
     140  assert_nothing_raised{ o.a += 1 }
     141  o.a = 1
     142  assert_nothing_raised{ o.a <<= 1 }
     143  o.a = 1
     144  assert_nothing_raised{ o.a &&= 1 }
     145
     146  o = { k: 1 }
     147  assert_nothing_raised{ o[:k] += 1 }
     148  o = { k: 1 }
     149  assert_nothing_raised{ o[:k] <<= 1 }
     150  o = { k: 1 }
     151  assert_nothing_raised{ o[:k] &&= 1 }
     152
     153  o = { k: 1 }
     154  assert_nothing_raised{ o[*[:k]] += 1 }
     155  o = { k: 1 }
     156  assert_nothing_raised{ o[*[:k]] <<= 1 }
     157  o = { k: 1 }
     158  assert_nothing_raised{ o[*[:k]] &&= 1 }
     159
     160  # NODE_YIELD
     161  def check_node_yield
     162    yield
     163  end
     164  assert_nothing_raised do
     165    check_node_yield{}
     166  end
     167
     168  # NODE_DXSTR
     169  assert_raise(NotImplementedError){ `#{:dynamic}` }
     170
     171  # NODE_XSTR
     172  assert_raise(NotImplementedError){ `static` }
     173
     174  # NODE_DREGX
     175  class Regexp; end
     176  assert_raise(NoMethodError){ /#{'dynamic'}tail/ }
     177  assert_raise(NoMethodError){ /#{'dynamic'}tail/iu }
     178
     179  # NODE_REGX
     180  assert_raise(NoMethodError){ /static/ }
     181  assert_raise(NoMethodError){ /static/iu }
     182  Object.remove_const :Regexp
     183
     184  # NODE_UNDEF
     185  assert_nothing_raised do
     186    class << Object.new
     187      undef inspect
     188    end
     189  end
     190
     191  # NODE_ALIAS
     192  assert_nothing_raised do
     193    class << Object.new
     194      alias inspect2 inspect
     195    end
     196  end
     197end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/enumerable.rb

    r321 r439  
    4646assert('Enumerable#detect', '15.3.2.2.4') do
    4747  assert_equal 1, [1,2,3].detect() { true }
    48   assert_equal 'a', [1,2,3].detect("a") { false }
     48  assert_equal 'a', [1,2,3].detect(->{"a"}) { false }
    4949end
    5050
     
    6565assert('Enumerable#find', '15.3.2.2.7') do
    6666  assert_equal 1, [1,2,3].find() { true }
    67   assert_equal 'a', [1,2,3].find("a") { false }
     67  assert_equal 'a', [1,2,3].find(->{"a"}) { false }
    6868end
    6969
    7070assert('Enumerable#find_all', '15.3.2.2.8') do
    71   assert_true [1,2,3,4,5,6,7,8,9].find_all() {|i| i%2 == 0}, [2,4,6,8]
     71  assert_equal [2,4,6,8], [1,2,3,4,5,6,7,8,9].find_all() {|i| i%2 == 0}
    7272end
    7373
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/exception.rb

    r331 r439  
    264264
    265265assert('Exception 14') do
    266   def exception_test14; UnknownConstant; end
     266  def (o = Object.new).exception_test14; UnknownConstant end
    267267  a = :ng
    268268  begin
    269     send(:exception_test14)
     269    o.__send__(:exception_test14)
    270270  rescue
    271271    a = :ok
     
    353353end
    354354
    355 assert('Exception#inspect without message') do
     355assert('Exception#inspect') do
    356356  assert_equal "Exception", Exception.new.inspect
     357  assert_equal "Exception", Exception.new("").inspect
     358  assert_equal "error! (Exception)", Exception.new("error!").inspect
    357359end
    358360
     
    399401  rescue => exception
    400402    GC.start
    401     assert_equal("#{__FILE__}:#{line}:in call",
     403    assert_equal("#{__FILE__}:#{line}",
    402404                 exception.backtrace.first)
    403405  end
     
    417419    [3].each do
    418420    end
    419     assert_equal("#{__FILE__}:#{line}:in call",
     421    assert_equal("#{__FILE__}:#{line}",
    420422                 exception.backtrace.first)
    421423  end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/float.rb

    r331 r439  
    11##
    22# Float ISO Test
     3
     4if Object.const_defined?(:Float)
    35
    46assert('Float', '15.2.9') do
     
    8183
    8284assert('Float#finite?', '15.2.9.3.9') do
    83   assert_true 3.123456789.finite?
    84   assert_false (1.0 / 0.0).finite?
     85  assert_predicate 3.123456789, :finite?
     86  assert_not_predicate 1.0 / 0.0, :finite?
    8587end
    8688
     
    138140  assert_raise(FloatDomainError){ nan.round }
    139141  assert_raise(FloatDomainError){ nan.round(-1) }
    140   assert_true(nan.round(1).nan?)
     142  assert_predicate(nan.round(1), :nan?)
    141143end
    142144
     
    177179
    178180assert('Float#nan?') do
    179   assert_true (0.0/0.0).nan?
    180   assert_false 0.0.nan?
    181   assert_false (1.0/0.0).nan?
    182   assert_false (-1.0/0.0).nan?
     181  assert_predicate(0.0/0.0, :nan?)
     182  assert_not_predicate(0.0, :nan?)
     183  assert_not_predicate(1.0/0.0, :nan?)
     184  assert_not_predicate(-1.0/0.0, :nan?)
    183185end
    184186
     
    204206  assert_equal(-1, -23.0 >> 128)
    205207end
     208
     209assert('Float#to_s') do
     210  uses_float = 4e38.infinite?  # enable MRB_USE_FLOAT?
     211
     212  assert_equal("Infinity", Float::INFINITY.to_s)
     213  assert_equal("-Infinity", (-Float::INFINITY).to_s)
     214  assert_equal("NaN", Float::NAN.to_s)
     215  assert_equal("0", 0.0.to_s)
     216  assert_equal("-0", -0.0.to_s)
     217  assert_equal("-3.25", -3.25.to_s)
     218  assert_equal("50", 50.0.to_s)
     219  assert_equal("0.0125", 0.0125.to_s)
     220  assert_equal("-0.0125", -0.0125.to_s)
     221  assert_equal("1.0e-10", 0.0000000001.to_s)
     222  assert_equal("-1.0e-10", -0.0000000001.to_s)
     223  assert_equal("1.0e+20", 1e20.to_s)
     224  assert_equal("-1.0e+20", -1e20.to_s)
     225  assert_equal("1.0e+16", 10000000000000000.0.to_s)
     226  assert_equal("-1.0e+16", -10000000000000000.0.to_s)
     227  assert_equal("100000", 100000.0.to_s)
     228  assert_equal("-100000", -100000.0.to_s)
     229  if uses_float
     230    assert_equal("1.0e+08", 100000000.0.to_s)
     231    assert_equal("-1.0e+08", -100000000.0.to_s)
     232    assert_equal("1.0e+07", 10000000.0.to_s)
     233    assert_equal("-1.0e+07", -10000000.0.to_s)
     234  else
     235    assert_equal("1.0e+15", 1000000000000000.0.to_s)
     236    assert_equal("-1.0e+15", -1000000000000000.0.to_s)
     237    assert_equal("100000000000000", 100000000000000.0.to_s)
     238    assert_equal("-100000000000000", -100000000000000.0.to_s)
     239  end
     240end
     241
     242assert('Float#eql?') do
     243  assert_operator(5.0, :eql?, 5.0)
     244  assert_not_operator(5.0, :eql?, 5)
     245  assert_not_operator(5.0, :eql?, "5.0")
     246end
     247
     248end # const_defined?(:Float)
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/hash.rb

    r331 r439  
    99  assert_true({ 'abc' => 'abc' } == { 'abc' => 'abc' })
    1010  assert_false({ 'abc' => 'abc' } ==  { 'cba' => 'cba' })
     11  assert_false({ :a => 1 } == true)
     12  skip unless Object.const_defined?(:Float)
    1113  assert_true({ :equal => 1 } == { :equal => 1.0 })
    12   assert_false({ :a => 1 } == true)
    1314end
    1415
     
    8384
    8485assert('Hash#delete', '15.2.13.4.8') do
    85   a = { 'abc' => 'abc' }
    86   b = { 'abc' => 'abc' }
     86  a = { 'abc' => 'ABC' }
     87  b = { 'abc' => 'ABC' }
    8788  b_tmp_1 = false
    8889  b_tmp_2 = false
    8990
    90   a.delete('abc')
     91  assert_equal 'ABC', a.delete('abc')
    9192  b.delete('abc') do |k|
    9293    b_tmp_1 = true
     
    352353assert('Hash#inspect') do
    353354  h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
     355  h["recur"] = h
    354356  ret = h.to_s
    355357
     
    357359  assert_include ret, '"a"=>100'
    358360  assert_include ret, '"d"=>400'
     361  assert_include ret, '"recur"=>{...}'
    359362end
    360363
     
    370373assert('Hash#freeze') do
    371374  h = {}.freeze
    372   assert_raise(RuntimeError) do
     375  assert_raise(FrozenError) do
    373376    h[:a] = 'b'
    374377  end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/integer.rb

    r331 r439  
    88assert('Integer#+', '15.2.8.3.1') do
    99  a = 1+1
    10   b = 1+1.0
     10  b = 1+1.0 if Object.const_defined?(:Float)
    1111
    1212  assert_equal 2, a
    13   assert_equal 2.0, b
     13  assert_equal 2.0, b if Object.const_defined?(:Float)
    1414
    1515  assert_raise(TypeError){ 0+nil }
     
    1818  c = Mrbtest::FIXNUM_MAX + 1
    1919  d = Mrbtest::FIXNUM_MAX.__send__(:+, 1)
     20
     21  skip unless Object.const_defined?(:Float)
    2022  e = Mrbtest::FIXNUM_MAX + 1.0
    2123  assert_equal Float, c.class
     
    2729assert('Integer#-', '15.2.8.3.2') do
    2830  a = 2-1
    29   b = 2-1.0
     31  b = 2-1.0 if Object.const_defined?(:Float)
    3032
    3133  assert_equal 1, a
    32   assert_equal 1.0, b
     34  assert_equal 1.0, b if Object.const_defined?(:Float)
    3335
    3436  c = Mrbtest::FIXNUM_MIN - 1
    3537  d = Mrbtest::FIXNUM_MIN.__send__(:-, 1)
     38
     39  skip unless Object.const_defined?(:Float)
    3640  e = Mrbtest::FIXNUM_MIN - 1.0
    3741  assert_equal Float, c.class
     
    4347assert('Integer#*', '15.2.8.3.3') do
    4448  a = 1*1
    45   b = 1*1.0
     49  b = 1*1.0 if Object.const_defined?(:Float)
    4650
    4751  assert_equal 1, a
    48   assert_equal 1.0, b
     52  assert_equal 1.0, b if Object.const_defined?(:Float)
    4953
    5054  assert_raise(TypeError){ 0*nil }
     
    5357  c = Mrbtest::FIXNUM_MAX * 2
    5458  d = Mrbtest::FIXNUM_MAX.__send__(:*, 2)
     59
     60  skip unless Object.const_defined?(:Float)
    5561  e = Mrbtest::FIXNUM_MAX * 2.0
    5662  assert_equal Float, c.class
     
    149155  assert_equal 23, 46 << -1
    150156
    151   # Left Shift by 31 is bitShift overflow to SignedInt
    152   assert_equal 2147483648, 1 << 31
    153 
    154   # -3 Left Shift by 30 is bitShift overflow to SignedInt
    155   assert_equal(-3221225472, -3 << 30)
     157  skip unless Object.const_defined?(:Float)
     158
     159  # Overflow to Fixnum
     160  assert_float 9223372036854775808.0, 1 << 63
     161  assert_float(-13835058055282163712.0, -3 << 62)
    156162end
    157163
     
    218224
    219225assert('Integer#to_f', '15.2.8.3.23') do
     226  skip unless Object.const_defined?(:Float)
    220227  assert_equal 1.0, 1.to_f
    221228end
     
    226233
    227234assert('Integer#to_s', '15.2.8.3.25') do
    228   assert_equal '1', 1.to_s
    229   assert_equal("-1", -1.to_s)
     235  assert_equal "1", 1.to_s
     236  assert_equal "-1", -1.to_s
     237  assert_equal "1010", 10.to_s(2)
     238  assert_equal "a", 10.to_s(36)
     239  assert_equal "-a", -10.to_s(36)
     240  assert_equal "30071", 12345.to_s(8)
     241  assert_raise(ArgumentError) { 10.to_s(-1) }
     242  assert_raise(ArgumentError) { 10.to_s(0) }
     243  assert_raise(ArgumentError) { 10.to_s(1) }
     244  assert_raise(ArgumentError) { 10.to_s(37) }
    230245end
    231246
     
    251266  assert_equal [ 1, -6], -13.divmod(-7)
    252267end
    253 
    254 # Not ISO specified
    255 
    256 assert('Integer#step') do
    257   a = []
    258   b = []
    259   1.step(3) do |i|
    260     a << i
    261   end
    262   1.step(6, 2) do |i|
    263     b << i
    264   end
    265 
    266   assert_equal [1, 2, 3], a
    267   assert_equal [1, 3, 5], b
    268 end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/kernel.rb

    r331 r439  
    3232# Kernel.eval is provided by the mruby-gem mrbgem. '15.3.1.2.3'
    3333
    34 assert('Kernel.global_variables', '15.3.1.2.4') do
    35   assert_equal Array, Kernel.global_variables.class
    36 end
    37 
    3834assert('Kernel.iterator?', '15.3.1.2.5') do
    3935  assert_false Kernel.iterator?
     
    5248  assert_equal Proc, m.class
    5349end
    54 
    55 # Not implemented at the moment
    56 #assert('Kernel.local_variables', '15.3.1.2.7') do
    57 #  Kernel.local_variables.class == Array
    58 #end
    5950
    6051assert('Kernel.loop', '15.3.1.2.8') do
     
    109100  assert_true __send__(:respond_to?, :nil?)
    110101  # test without argument and without block
    111   assert_equal  Array, __send__(:public_methods).class
     102  assert_equal String, __send__(:to_s).class
    112103end
    113104
     
    177168  assert_false b.respond_to?(:test)
    178169  assert_true c.respond_to?(:test)
     170
     171  a.freeze
     172  d = a.clone
     173  assert_true d.frozen?
    179174end
    180175
     
    246241  assert_true a.respond_to?(:test_method)
    247242  assert_false b.respond_to?(:test_method)
     243
     244  assert_raise(FrozenError) { Object.new.freeze.extend(Test4ExtendModule) }
     245  assert_raise(FrozenError, TypeError) { :sym.extend(Test4ExtendModule) }
    248246end
    249247
     
    263261  assert_equal 0, 0.freeze
    264262  assert_equal :a, :a.freeze
    265 end
    266 
    267 assert('Kernel#global_variables', '15.3.1.3.14') do
    268   assert_equal Array, global_variables.class
     263  assert_equal true, true.freeze
     264  assert_equal false, false.freeze
     265  assert_equal nil, nil.freeze
     266  skip unless Object.const_defined?(:Float)
     267  assert_equal 0.0, 0.0.freeze
     268end
     269
     270assert('Kernel#frozen?') do
     271  assert_false "".frozen?
     272  assert_true "".freeze.frozen?
     273  assert_true 0.frozen?
     274  assert_true :a.frozen?
     275  assert_true true.frozen?
     276  assert_true false.frozen?
     277  assert_true nil.frozen?
     278  skip unless Object.const_defined?(:Float)
     279  assert_true 0.0.frozen?
    269280end
    270281
     
    278289  assert_equal String, s.class
    279290  assert_equal "main", s
    280 end
    281 
    282 assert('Kernel#instance_variable_defined?', '15.3.1.3.20') do
    283   o = Object.new
    284   o.instance_variable_set(:@a, 1)
    285 
    286   assert_true o.instance_variable_defined?("@a")
    287   assert_false o.instance_variable_defined?("@b")
    288   assert_true o.instance_variable_defined?("@a"[0,2])
    289   assert_true o.instance_variable_defined?("@abc"[0,2])
    290 end
    291 
    292 assert('Kernel#instance_variables', '15.3.1.3.23') do
    293   o = Object.new
    294   o.instance_eval do
    295     @a = 11
    296     @b = 12
    297   end
    298   ivars = o.instance_variables
    299 
    300   assert_equal Array, ivars.class,
    301   assert_equal(2, ivars.size)
    302   assert_true ivars.include?(:@a)
    303   assert_true ivars.include?(:@b)
    304291end
    305292
     
    335322end
    336323
    337 # Not implemented yet
    338 #assert('Kernel#local_variables', '15.3.1.3.28') do
    339 #  local_variables.class == Array
    340 #end
    341 
    342324assert('Kernel#loop', '15.3.1.3.29') do
    343325  i = 0
     
    360342  assert_equal 'A call to no_method_named_this', mm_test.no_method_named_this
    361343
     344  class SuperMMTestClass < MMTestClass
     345    def no_super_method_named_this
     346      super
     347    end
     348  end
     349  super_mm_test = SuperMMTestClass.new
     350  assert_equal 'A call to no_super_method_named_this', super_mm_test.no_super_method_named_this
     351
     352  class NoSuperMethodTestClass
     353    def no_super_method_named_this
     354      super
     355    end
     356  end
     357  no_super_test = NoSuperMethodTestClass.new
     358  msg = "undefined method 'no_super_method_named_this'"
     359  assert_raise_with_message(NoMethodError, msg) do
     360    no_super_test.no_super_method_named_this
     361  end
     362
    362363  a = String.new
    363   begin
     364  msg = "undefined method 'no_method_named_this'"
     365  assert_raise_with_message(NoMethodError, msg) do
    364366    a.no_method_named_this
    365   rescue NoMethodError => e
    366     assert_equal "undefined method 'no_method_named_this' for \"\"", e.message
    367   end
    368 
    369   class ShortInspectClass
    370     def inspect
    371       'An inspect string'
    372     end
    373   end
    374   b = ShortInspectClass.new
    375   begin
    376     b.no_method_named_this
    377   rescue NoMethodError => e
    378     assert_equal "undefined method 'no_method_named_this' for An inspect string", e.message
    379   end
    380 
    381   class LongInspectClass
    382     def inspect
    383       "A" * 70
    384     end
    385   end
    386   c = LongInspectClass.new
    387   begin
    388     c.no_method_named_this
    389   rescue NoMethodError => e
    390     assert_equal "undefined method 'no_method_named_this' for #{c.to_s}", e.message
    391   end
    392 
    393   class NoInspectClass
    394     undef inspect
    395   end
    396   d = NoInspectClass.new
    397   begin
    398     d.no_method_named_this
    399   rescue NoMethodError => e
    400     assert_equal "undefined method 'no_method_named_this' for #{d.to_s}", e.message
    401   end
    402 end
    403 
    404 assert('Kernel#methods', '15.3.1.3.31') do
    405   assert_equal Array, methods.class
     367  end
    406368end
    407369
     
    429391# Kernel#print is defined in mruby-print mrbgem. '15.3.1.3.35'
    430392
    431 assert('Kernel#private_methods', '15.3.1.3.36') do
    432   assert_equal Array, private_methods.class
    433 end
    434 
    435 assert('Kernel#protected_methods', '15.3.1.3.37') do
    436   assert_equal Array, protected_methods.class
    437 end
    438 
    439 assert('Kernel#public_methods', '15.3.1.3.38') do
    440   assert_equal Array, public_methods.class
    441   class Foo
    442     def foo
    443     end
    444   end
    445   assert_equal [:foo], Foo.new.public_methods(false)
    446 end
    447 
    448393# Kernel#puts is defined in mruby-print mrbgem. '15.3.1.3.39'
    449394
     
    471416  tri = Test4RemoveInstanceVar.new
    472417  assert_equal 99, tri.var
    473   tri.remove
     418  assert_equal 99, tri.remove
    474419  assert_equal nil, tri.var
    475   assert_raise NameError do
    476     tri.remove
    477   end
     420  assert_raise(NameError) { tri.remove }
     421  assert_raise(NameError) { tri.remove_instance_variable(:var) }
     422  assert_raise(FrozenError) { tri.freeze.remove }
     423  assert_raise(FrozenError, NameError) { :a.remove_instance_variable(:@v) }
    478424end
    479425
     
    506452end
    507453
    508 assert('Kernel#send', '15.3.1.3.44') do
    509   # test with block
    510   l = send(:lambda) do
    511     true
    512   end
    513 
    514   assert_true l.call
    515   assert_equal l.class, Proc
    516   # test with argument
    517   assert_true send(:respond_to?, :nil?)
    518   # test without argument and without block
    519   assert_equal send(:public_methods).class, Array
    520 end
    521 
    522 assert('Kernel#singleton_methods', '15.3.1.3.45') do
    523   assert_equal singleton_methods.class, Array
    524 end
    525 
    526454assert('Kernel#to_s', '15.3.1.3.46') do
    527455  assert_equal to_s.class, String
    528 end
    529 
    530 assert('Kernel#to_s on primitives') do
    531   begin
    532     Fixnum.alias_method :to_s_, :to_s
    533     Fixnum.remove_method :to_s
    534 
    535     assert_nothing_raised do
    536       # segfaults if mrb_cptr is used
    537       1.to_s
    538     end
    539   ensure
    540     Fixnum.alias_method :to_s, :to_s_
    541     Fixnum.remove_method :to_s_
    542   end
    543 end
    544 
    545 assert('Kernel.local_variables', '15.3.1.2.7') do
    546   a, b = 0, 1
    547   a += b
    548 
    549   vars = Kernel.local_variables.sort
    550   assert_equal [:a, :b, :vars], vars
    551 
    552   assert_equal [:a, :b, :c, :vars], Proc.new { |a, b|
    553     c = 2
    554     Kernel.local_variables.sort
    555   }.call(-1, -2)
    556456end
    557457
     
    598498end
    599499
    600 assert('Kernel#global_variables') do
    601   variables = global_variables
    602   1.upto(9) do |i|
    603     assert_equal variables.include?(:"$#{i}"), true
    604   end
    605 end
    606 
    607 assert('Kernel#define_singleton_method') do
    608   o = Object.new
    609   ret = o.define_singleton_method(:test_method) do
    610     :singleton_method_ok
    611   end
    612   assert_equal :test_method, ret
    613   assert_equal :singleton_method_ok, o.test_method
    614 end
    615 
    616500assert('stack extend') do
    617501  def recurse(count, stop)
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/lang.rb

    r331 r439  
    99# For example, the following mruby code:
    1010#
    11 #   if i > 0 and i < 10 then
     11#   if i > 0 and i < 10
    1212#
    1313# compiles to the following byte code:
     
    2828assert('and', '11.2.3') do
    2929  a = 1
    30   if a > 0 and a < 10 then
     30  if a > 0 and a < 10
    3131    b = 1
    3232  else
     
    3535  assert_equal 1, b
    3636
    37   if a < 0 and a < 10 then
     37  if a < 0 and a < 10
    3838    b = 1
    3939  else
     
    4242  assert_equal 0, b
    4343
    44   if a < 0 and a > 10 then
     44  if a < 0 and a > 10
    4545    b = 1
    4646  else
     
    5252assert('or','11.2.4') do
    5353  a = 1
    54   if a > 0 or a < 10 then
     54  if a > 0 or a < 10
    5555    b = 1
    5656  else
     
    5959  assert_equal 1, b
    6060
    61   if a < 0 or a < 10 then
     61  if a < 0 or a < 10
    6262    b = 1
    6363  else
     
    6666  assert_equal 1, b
    6767
    68   if a < 0 or a > 10 then
     68  if a < 0 or a > 10
    6969    b = 1
    7070  else
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/literals.rb

    r331 r439  
    2323  assert_equal 999, 0d999
    2424  assert_equal 999, 0D999
    25   # decimal seperator
     25  # decimal separator
    2626  assert_equal 10000000, 10_000_000
    2727  assert_equal       10, 1_0
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/module.rb

    r331 r439  
    44def labeled_module(name, &block)
    55  Module.new do
    6     singleton_class.class_eval do
     6    (class <<self; self end).class_eval do
    77      define_method(:to_s) { name }
    88      alias_method :inspect, :to_s
     
    1414def labeled_class(name, supklass = Object, &block)
    1515  Class.new(supklass) do
    16     singleton_class.class_eval do
     16    (class <<self; self end).class_eval do
    1717      define_method(:to_s) { name }
    1818      alias_method :inspect, :to_s
     
    2222end
    2323
     24def assert_uninitialized_const(&block)
     25  assert_raise_with_message_pattern(NameError, "uninitialized constant *", &block)
     26end
     27
     28def assert_wrong_const_name(&block)
     29  assert_raise_with_message_pattern(NameError, "wrong constant name *", &block)
     30end
     31
    2432assert('Module', '15.2.2') do
    2533  assert_equal Class, Module.class
    2634end
    2735
     36assert('Module#alias_method', '15.2.2.4.8') do
     37  cls = Class.new do
     38    def foo
     39      "FOO"
     40    end
     41  end
     42
     43  assert_same(cls, cls.alias_method(:bar, :foo))
     44  assert_equal("FOO", cls.new.bar)
     45end
     46
    2847# TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do
    29 
    30 # TODO not implemented ATM assert('Module.nesting', '15.2.2.3.2') do
    3148
    3249assert('Module#ancestors', '15.2.2.4.9') do
    3350  class Test4ModuleAncestors
    3451  end
    35   sc = Test4ModuleAncestors.singleton_class
    3652  r = String.ancestors
    3753
     
    5268
    5369  assert_equal Test4AppendFeatures2, Test4AppendFeatures2.const_get(:Const4AppendFeatures2)
     70  assert_raise(FrozenError) { Module.new.append_features Class.new.freeze }
    5471end
    5572
     
    202219    end
    203220  end
    204   r = Test4ClassEval.instance_methods
    205 
    206221  assert_equal 11, Test4ClassEval.class_eval{ @a }
    207222  assert_equal 12, Test4ClassEval.class_eval{ @b }
    208   assert_equal Array, r.class
    209   assert_true r.include?(:method1)
    210 end
    211 
    212 assert('Module#class_variable_defined?', '15.2.2.4.16') do
    213   class Test4ClassVariableDefined
    214     @@cv = 99
    215   end
    216 
    217   assert_true Test4ClassVariableDefined.class_variable_defined?(:@@cv)
    218   assert_false Test4ClassVariableDefined.class_variable_defined?(:@@noexisting)
    219 end
    220 
    221 assert('Module#class_variable_get', '15.2.2.4.17') do
    222   class Test4ClassVariableGet
    223     @@cv = 99
    224   end
    225 
    226   assert_equal 99, Test4ClassVariableGet.class_variable_get(:@@cv)
    227 end
    228 
    229 assert('Module#class_variable_set', '15.2.2.4.18') do
    230   class Test4ClassVariableSet
    231     @@foo = 100
    232     def foo
    233       @@foo
    234     end
    235   end
    236 
    237   assert_true Test4ClassVariableSet.class_variable_set(:@@cv, 99)
    238   assert_true Test4ClassVariableSet.class_variable_set(:@@foo, 101)
    239   assert_true Test4ClassVariableSet.class_variables.include? :@@cv
    240   assert_equal 99, Test4ClassVariableSet.class_variable_get(:@@cv)
    241   assert_equal 101, Test4ClassVariableSet.new.foo
    242 end
    243 
    244 assert('Module#class_variables', '15.2.2.4.19') do
    245   class Test4ClassVariables1
    246     @@var1 = 1
    247   end
    248   class Test4ClassVariables2 < Test4ClassVariables1
    249     @@var2 = 2
    250   end
    251 
    252   assert_equal [:@@var1], Test4ClassVariables1.class_variables
    253   assert_equal [:@@var2, :@@var1], Test4ClassVariables2.class_variables
     223  assert_equal true, Test4ClassEval.new.respond_to?(:method1)
    254224end
    255225
     
    261231  assert_true Test4ConstDefined.const_defined?(:Const4Test4ConstDefined)
    262232  assert_false Test4ConstDefined.const_defined?(:NotExisting)
     233  assert_wrong_const_name{ Test4ConstDefined.const_defined?(:wrong_name) }
    263234end
    264235
     
    269240
    270241  assert_equal 42, Test4ConstGet.const_get(:Const4Test4ConstGet)
     242  assert_equal 42, Test4ConstGet.const_get("Const4Test4ConstGet")
     243  assert_equal 42, Object.const_get("Test4ConstGet::Const4Test4ConstGet")
     244
     245  assert_raise(TypeError){ Test4ConstGet.const_get(123) }
     246  assert_uninitialized_const{ Test4ConstGet.const_get(:I_DO_NOT_EXIST) }
     247  assert_uninitialized_const{ Test4ConstGet.const_get("I_DO_NOT_EXIST::ME_NEITHER") }
     248  assert_wrong_const_name{ Test4ConstGet.const_get(:wrong_name) }
     249end
     250
     251assert('Module#const_set', '15.2.2.4.23') do
     252  module Test4ConstSet
     253    Const4Test4ConstSet = 42
     254  end
     255
     256  assert_equal 23, Test4ConstSet.const_set(:Const4Test4ConstSet, 23)
     257  assert_equal 23, Test4ConstSet.const_get(:Const4Test4ConstSet)
     258  ["", "wrongNAME", "Wrong-Name"].each do |n|
     259    assert_wrong_const_name { Test4ConstSet.const_set(n, 1) }
     260  end
     261end
     262
     263assert('Module#remove_const', '15.2.2.4.40') do
     264  module Test4RemoveConst
     265    ExistingConst = 23
     266  end
     267
     268  assert_equal 23, Test4RemoveConst.remove_const(:ExistingConst)
     269  assert_false Test4RemoveConst.const_defined?(:ExistingConst)
     270  assert_raise_with_message_pattern(NameError, "constant * not defined") do
     271    Test4RemoveConst.remove_const(:NonExistingConst)
     272  end
     273  %i[x X!].each do |n|
     274    assert_wrong_const_name { Test4RemoveConst.remove_const(n) }
     275  end
     276  assert_raise(FrozenError) { Test4RemoveConst.freeze.remove_const(:A) }
    271277end
    272278
     
    281287end
    282288
    283 assert('Module#const_get', '15.2.2.4.23') do
    284   module Test4ConstSet
    285     Const4Test4ConstSet = 42
    286   end
    287 
    288   assert_true Test4ConstSet.const_set(:Const4Test4ConstSet, 23)
    289   assert_equal 23, Test4ConstSet.const_get(:Const4Test4ConstSet)
    290 end
    291 
    292 assert('Module#constants', '15.2.2.4.24') do
    293   $n = []
    294   module TestA
    295     C = 1
    296   end
    297   class TestB
    298     include TestA
    299     C2 = 1
    300     $n = constants.sort
    301   end
    302 
    303   assert_equal [ :C ], TestA.constants
    304   assert_equal [ :C, :C2 ], $n
     289assert('Module#extend_object', '15.2.2.4.25') do
     290  cls = Class.new
     291  mod = Module.new { def foo; end }
     292  a = cls.new
     293  b = cls.new
     294  mod.extend_object(b)
     295  assert_false a.respond_to?(:foo)
     296  assert_true b.respond_to?(:foo)
     297  assert_raise(FrozenError) { mod.extend_object(cls.new.freeze) }
     298  assert_raise(FrozenError, TypeError) { mod.extend_object(1) }
    305299end
    306300
     
    310304  end
    311305  module Test4Include2
    312     include Test4Include
     306    @include_result = include Test4Include
     307    class << self
     308      attr_reader :include_result
     309    end
    313310  end
    314311
    315312  assert_equal 42, Test4Include2.const_get(:Const4Include)
     313  assert_equal Test4Include2, Test4Include2.include_result
     314  assert_raise(FrozenError) { Module.new.freeze.include Test4Include }
    316315end
    317316
     
    345344end
    346345
    347 assert('Module#included_modules', '15.2.2.4.30') do
    348   module Test4includedModules
    349   end
    350   module Test4includedModules2
    351     include Test4includedModules
    352   end
    353   r = Test4includedModules2.included_modules
    354 
    355   assert_equal Array, r.class
    356   assert_true r.include?(Test4includedModules)
    357 end
    358 
    359346assert('Module#initialize', '15.2.2.4.31') do
    360347  assert_kind_of Module, Module.new
    361348  mod = Module.new { def hello; "hello"; end }
    362   assert_equal [:hello], mod.instance_methods
     349  cls = Class.new{include mod}
     350  assert_true cls.new.respond_to?(:hello)
    363351  a = nil
    364352  mod = Module.new { |m| a = m }
    365353  assert_equal mod, a
    366 end
    367 
    368 assert('Module#instance_methods', '15.2.2.4.33') do
    369   module Test4InstanceMethodsA
    370     def method1()  end
    371   end
    372   class Test4InstanceMethodsB
    373     def method2()  end
    374   end
    375   class Test4InstanceMethodsC < Test4InstanceMethodsB
    376     def method3()  end
    377   end
    378 
    379   r = Test4InstanceMethodsC.instance_methods(true)
    380 
    381   assert_equal [:method1], Test4InstanceMethodsA.instance_methods
    382   assert_equal [:method2], Test4InstanceMethodsB.instance_methods(false)
    383   assert_equal [:method3], Test4InstanceMethodsC.instance_methods(false)
    384   assert_equal Array, r.class
    385   assert_true r.include?(:method3)
    386   assert_true r.include?(:method2)
    387354end
    388355
     
    410377end
    411378
    412 
    413379assert('Module#module_eval', '15.2.2.4.35') do
    414380  module Test4ModuleEval
     
    419385  assert_equal 11, Test4ModuleEval.module_eval{ @a }
    420386  assert_equal 12, Test4ModuleEval.module_eval{ @b }
    421 end
    422 
    423 assert('Module#remove_class_variable', '15.2.2.4.39') do
    424   class Test4RemoveClassVariable
    425     @@cv = 99
    426   end
    427 
    428   assert_equal 99, Test4RemoveClassVariable.remove_class_variable(:@@cv)
    429   assert_false Test4RemoveClassVariable.class_variables.include? :@@cv
    430 end
    431 
    432 assert('Module#remove_const', '15.2.2.4.40') do
    433   module Test4RemoveConst
    434     ExistingConst = 23
    435   end
    436 
    437   result = Test4RemoveConst.module_eval { remove_const :ExistingConst }
    438 
    439   name_error = false
    440   begin
    441     Test4RemoveConst.module_eval { remove_const :NonExistingConst }
    442   rescue NameError
    443     name_error = true
    444   end
    445 
    446   # Constant removed from Module
    447   assert_false Test4RemoveConst.const_defined? :ExistingConst
    448   # Return value of binding
    449   assert_equal 23, result
    450   # Name Error raised when Constant doesn't exist
    451   assert_true name_error
    452 end
    453 
    454 assert('Module#remove_method', '15.2.2.4.41') do
    455   module Test4RemoveMethod
    456     class Parent
    457       def hello
    458       end
    459      end
    460 
    461      class Child < Parent
    462       def hello
    463       end
    464     end
    465   end
    466 
    467   assert_true Test4RemoveMethod::Child.class_eval{ remove_method :hello }
    468   assert_true Test4RemoveMethod::Child.instance_methods.include? :hello
    469   assert_false Test4RemoveMethod::Child.instance_methods(false).include? :hello
    470387end
    471388
     
    490407  assert_false Test4UndefMethod::Child.new.respond_to?(:hello)
    491408  assert_false Test4UndefMethod::GrandChild.new.respond_to?(:hello)
    492   assert_false Test4UndefMethod::Child.instance_methods(false).include? :hello
    493409end
    494410
    495411# Not ISO specified
     412
     413assert('Module#dup') do
     414  module TestModuleDup
     415    @@cvar = :cvar
     416    class << self
     417      attr_accessor :cattr
     418      def cmeth; :cmeth end
     419    end
     420    def cvar; @@cvar end
     421    def imeth; :imeth end
     422    self.cattr = :cattr
     423  end
     424
     425  m = TestModuleDup.dup
     426  o = Object.include(m).new
     427  assert_equal(:cattr, m.cattr)
     428  assert_equal(:cmeth, m.cmeth)
     429  assert_equal(:cvar, o.cvar)
     430  assert_equal(:imeth, o.imeth)
     431  assert_match("#<Module:0x*>", m.to_s)
     432  assert_not_predicate(m, :frozen?)
     433  assert_not_predicate(TestModuleDup.freeze.dup, :frozen?)
     434end
    496435
    497436assert('Module#define_method') do
     
    507446end
    508447
     448assert 'Module#prepend_features' do
     449  mod = Module.new { def m; :mod end }
     450  cls = Class.new { def m; :cls end }
     451  assert_equal :cls, cls.new.m
     452  mod.prepend_features(cls)
     453  assert_equal :mod, cls.new.m
     454  assert_raise(FrozenError) { Module.new.prepend_features(Class.new.freeze) }
     455end
     456
    509457# @!group prepend
    510458  assert('Module#prepend') do
     
    539487    expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2]
    540488    assert_equal(expected, obj.m1)
     489  end
     490
     491  assert('Module#prepend result') do
     492    module TestPrepended; end
     493    module TestPrependResult
     494      @prepend_result = prepend TestPrepended
     495      class << self
     496        attr_reader :prepend_result
     497      end
     498    end
     499
     500    assert_equal TestPrependResult, TestPrependResult.prepend_result
    541501  end
    542502
     
    573533    bug8357 = '[ruby-core:54742] [Bug #8357]'
    574534    assert_kind_of(b, c.new, bug8357)
    575   end
    576 
    577   assert('Moduler#prepend + #instance_methods') do
    578     bug6655 = '[ruby-core:45915]'
    579     assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655)
    580   end
    581 
    582   assert 'Module#prepend + #singleton_methods' do
    583     o = Object.new
    584     o.singleton_class.class_eval {prepend Module.new}
    585     assert_equal([], o.singleton_methods)
    586   end
    587 
    588   assert 'Module#prepend + #remove_method' do
    589     c = Class.new do
    590       prepend Module.new { def foo; end }
    591     end
    592     assert_raise(NameError) do
    593       c.class_eval do
    594         remove_method(:foo)
    595       end
    596     end
    597     c.class_eval do
    598       def foo; end
    599     end
    600     removed = nil
    601     c.singleton_class.class_eval do
    602       define_method(:method_removed) {|id| removed = id}
    603     end
    604     assert_nothing_raised(NoMethodError, NameError, '[Bug #7843]') do
    605       c.class_eval do
    606         remove_method(:foo)
    607       end
    608     end
    609     assert_equal(:foo, removed)
    610535  end
    611536
     
    650575  end
    651576
    652   assert 'Module#prepend #instance_methods(false)' do
    653     bug6660 = '[ruby-dev:45863]'
    654     assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
    655     assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
    656   end
    657 
    658577  assert 'cyclic Module#prepend' do
    659578    bug7841 = '[ruby-core:52205] [Bug #7841]'
     
    666585  end
    667586
    668   # these assertions will not run without a #assert_seperately method
     587  # these assertions will not run without a #assert_separately method
    669588  #assert 'test_prepend_optmethod' do
    670589  #  bug7983 = '[ruby-dev:47124] [Bug #7983]'
     
    682601
    683602  # mruby has no visibility control
    684   assert 'Module#prepend visibility' do
    685     bug8005 = '[ruby-core:53106] [Bug #8005]'
    686     c = Class.new do
    687       prepend Module.new {}
    688       def foo() end
    689       protected :foo
    690     end
    691     a = c.new
    692     assert_true a.respond_to?(:foo), bug8005
    693     assert_nothing_raised(NoMethodError, bug8005) {a.send :foo}
    694   end
     603  # assert 'Module#prepend visibility' do
     604  #   bug8005 = '[ruby-core:53106] [Bug #8005]'
     605  #   c = Class.new do
     606  #     prepend Module.new {}
     607  #     def foo() end
     608  #     protected :foo
     609  #   end
     610  #   a = c.new
     611  #   assert_true a.respond_to?(:foo), bug8005
     612  #   assert_nothing_raised(bug8005) {a.send :foo}
     613  # end
    695614
    696615  # mruby has no visibility control
    697   assert 'Module#prepend inherited visibility' do
    698     bug8238 = '[ruby-core:54105] [Bug #8238]'
    699     module Test4PrependVisibilityInherited
    700       class A
    701         def foo() A; end
    702         private :foo
    703       end
    704       class B < A
    705         public :foo
    706         prepend Module.new
    707       end
    708     end
    709     assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}")
    710   end
    711 
    712   assert 'Module#prepend + #included_modules' do
    713     bug8025 = '[ruby-core:53158] [Bug #8025]'
    714     mixin = labeled_module("mixin")
    715     c = labeled_module("c") {prepend mixin}
    716     im = c.included_modules
    717     assert_not_include(im, c, bug8025)
    718     assert_include(im, mixin, bug8025)
    719     c1 = labeled_class("c1") {prepend mixin}
    720     c2 = labeled_class("c2", c1)
    721     im = c2.included_modules
    722     assert_not_include(im, c1, bug8025)
    723     assert_not_include(im, c2, bug8025)
    724     assert_include(im, mixin, bug8025)
    725   end
    726 
    727   assert 'Module#prepend super in alias' do
    728     skip "super does not currently work in aliased methods"
    729     bug7842 = '[Bug #7842]'
    730 
    731     p = labeled_module("P") do
    732       def m; "P"+super; end
    733     end
    734 
    735     a = labeled_class("A") do
    736       def m; "A"; end
    737     end
    738 
    739     b = labeled_class("B", a) do
    740       def m; "B"+super; end
    741       alias m2 m
    742       prepend p
    743       alias m3 m
    744     end
    745 
    746     assert_nothing_raised do
    747       assert_equal("BA", b.new.m2, bug7842)
    748     end
    749 
    750     assert_nothing_raised do
    751       assert_equal("PBA", b.new.m3, bug7842)
    752     end
    753   end
     616  # assert 'Module#prepend inherited visibility' do
     617  #   bug8238 = '[ruby-core:54105] [Bug #8238]'
     618  #   module Test4PrependVisibilityInherited
     619  #     class A
     620  #       def foo() A; end
     621  #       private :foo
     622  #     end
     623  #     class B < A
     624  #       public :foo
     625  #       prepend Module.new
     626  #     end
     627  #   end
     628  #   assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}")
     629  # end
     630
     631  # assert 'Module#prepend super in alias' do
     632  #   skip "super does not currently work in aliased methods"
     633  #   bug7842 = '[Bug #7842]'
     634
     635  #   p = labeled_module("P") do
     636  #     def m; "P"+super; end
     637  #   end
     638
     639  #   a = labeled_class("A") do
     640  #     def m; "A"; end
     641  #   end
     642
     643  #   b = labeled_class("B", a) do
     644  #     def m; "B"+super; end
     645  #     alias m2 m
     646  #     prepend p
     647  #     alias m3 m
     648  #   end
     649
     650  #   assert_nothing_raised do
     651  #     assert_equal("BA", b.new.m2, bug7842)
     652  #   end
     653
     654  #   assert_nothing_raised do
     655  #     assert_equal("PBA", b.new.m3, bug7842)
     656  #   end
     657  # end
    754658
    755659  assert 'Module#prepend each class' do
     
    774678  end
    775679
    776   # requires #assert_seperately
     680  # requires #assert_separately
    777681  #assert 'Module#prepend call super' do
    778682  #  assert_separately([], <<-'end;') #do
     
    785689  #  end;
    786690  #end
     691
     692  assert 'Module#prepend to frozen class' do
     693    assert_raise(FrozenError) { Class.new.freeze.prepend Module.new }
     694  end
    787695# @!endgroup prepend
    788696
    789697assert('Module#to_s') do
    790   module Test4to_sModules
    791   end
    792 
    793   assert_equal 'Test4to_sModules', Test4to_sModules.to_s
     698  module Outer
     699    class Inner; end
     700    const_set :SetInner, Class.new
     701  end
     702
     703  assert_equal 'Outer', Outer.to_s
     704  assert_equal 'Outer::Inner', Outer::Inner.to_s
     705  assert_equal 'Outer::SetInner', Outer::SetInner.to_s
     706
     707  outer = Module.new do
     708    const_set :SetInner, Class.new
     709  end
     710  Object.const_set :SetOuter, outer
     711
     712  assert_equal 'SetOuter', SetOuter.to_s
     713  assert_equal 'SetOuter::SetInner', SetOuter::SetInner.to_s
     714
     715  assert_match "#<Module:0x*>", Module.new.to_s
     716  assert_match "#<Class:0x*>", Class.new.to_s
     717
     718  assert_equal "FrozenClassToS", (FrozenClassToS = Class.new.freeze).to_s
     719  assert_equal "Outer::A", (Outer::A = Module.new.freeze).to_s
     720  assert_match "#<Module:0x*>::A", (Module.new::A = Class.new.freeze).to_s
    794721end
    795722
     
    819746  end
    820747
    821   C1.new
    822   C2.new
     748  assert_kind_of(M1, C1.new)
     749  assert_kind_of(M1, C2.new)
    823750end
    824751
     
    834761  end
    835762
    836   B.new.foo
     763  assert_true(B.new.foo)
    837764end
    838765
     
    849776  assert_raise(TypeError) { module 0::M1 end }
    850777  assert_raise(TypeError) { module []::M2 end }
     778end
     779
     780assert('module to return the last value') do
     781  m = module M; :m end
     782  assert_equal(m, :m)
     783end
     784
     785assert('module to return nil if body is empty') do
     786  assert_nil(module M end)
    851787end
    852788
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/numeric.rb

    r321 r439  
    22# Numeric ISO Test
    33
     4def assert_step(exp, receiver, args, inf: false)
     5  act = []
     6  ret = receiver.step(*args) do |i|
     7    act << i
     8    break if inf && exp.size == act.size
     9  end
     10  expr = "#{receiver.inspect}.step(#{args.map(&:inspect).join(', ')})"
     11  assert "assert_step" do
     12    assert_true(exp.eql?(act), "#{expr}: counters", assertion_diff(exp, act))
     13    assert_same(receiver, ret, "#{expr}: return value") unless inf
     14  end
     15end
     16
    417assert('Numeric', '15.2.7') do
    5   assert_equal Class, Numeric.class
     18  assert_equal(Class, Numeric.class)
    619end
    720
     
    1629assert('Numeric#abs', '15.2.7.4.3') do
    1730  assert_equal(1, 1.abs)
     31  skip unless Object.const_defined?(:Float)
    1832  assert_equal(1.0, -1.abs)
    19 end
    20 
    21 assert('Numeric#pow') do
    22   assert_equal(8, 2 ** 3)
    23   assert_equal(-8, -2 ** 3)
    24   assert_equal(1, 2 ** 0)
    25   assert_equal(1, 2.2 ** 0)
    26   assert_equal(0.5, 2 ** -1)
    2733end
    2834
     
    4046
    4147assert('Numeric#**') do
    42   assert_equal 8.0, 2.0**3
     48  assert_equal(8, 2 ** 3)
     49  assert_equal(-8, -2 ** 3)
     50  assert_equal(1, 2 ** 0)
     51  skip unless Object.const_defined?(:Float)
     52  assert_equal(1.0, 2.2 ** 0)
     53  assert_equal(0.5, 2 ** -1)
     54  assert_equal(8.0, 2.0**3)
    4355end
     56
     57assert('Numeric#step') do
     58  assert_raise(ArgumentError) { 1.step(2, 0) { break } }
     59  assert_step([2, 3, 4], 2, [4])
     60  assert_step([10, 8, 6, 4, 2], 10, [1, -2])
     61  assert_step([], 2, [1, 3])
     62  assert_step([], -2, [-1, -3])
     63  assert_step([10, 11, 12, 13], 10, [], inf: true)
     64  assert_step([10, 7, 4], 10, [nil, -3], inf: true)
     65
     66  skip unless Object.const_defined?(:Float)
     67  inf = Float::INFINITY
     68  assert_raise(ArgumentError) { 1.step(2, 0.0) { break } }
     69  assert_step([2.0, 3.0, 4.0], 2, [4.0])
     70  assert_step([7.0, 4.0, 1.0, -2.0], 7, [-4, -3.0])
     71  assert_step([2.0, 3.0, 4.0], 2.0, [4])
     72  assert_step([10.0, 11.0, 12.0, 13.0], 10.0, [], inf: true)
     73  assert_step([10.0, 7.0, 4.0], 10, [nil, -3.0], inf: true)
     74  assert_step([1.0], 1, [nil, inf])
     75  assert_step([1.0], 1, [nil, -inf])
     76  assert_step([1.0], 1, [3, inf])
     77  assert_step([], 1, [-3, inf])
     78  assert_step([], 1, [3, -inf])
     79  assert_step([1.0], 1, [-3, -inf])
     80  assert_step([1.0], 1, [inf, inf])
     81  assert_step([], 1, [inf, -inf])
     82  assert_step([], 1, [-inf, inf])
     83  assert_step([1.0], 1, [-inf, -inf])
     84  assert_step([], inf, [2])
     85  assert_step([], inf, [-2])
     86  assert_step([], inf, [2, 3])
     87  assert_step([inf, inf, inf], inf, [2, -3], inf: true)
     88  assert_step([], inf, [2, inf])
     89  assert_step([inf], inf, [2, -inf])
     90  assert_step([], inf, [-2, inf])
     91  assert_step([inf], inf, [-2, -inf])
     92  assert_step([], inf, [-2, 3])
     93  assert_step([inf, inf, inf], inf, [-2, -3], inf: true)
     94  assert_step([inf], inf, [inf])
     95  assert_step([], inf, [-inf])
     96  assert_step([inf], inf, [inf, inf])
     97  assert_step([inf], inf, [inf, -inf])
     98  assert_step([inf], inf, [-inf, -inf])
     99  assert_step([-inf, -inf, -inf], -inf, [2], inf: true)
     100  assert_step([-inf, -inf, -inf], -inf, [-2], inf: true)
     101  assert_step([-inf, -inf, -inf], -inf, [2, 3], inf: true)
     102  assert_step([], -inf, [2, -3])
     103  assert_step([-inf], -inf, [2, inf])
     104  assert_step([], -inf, [2, -inf])
     105  assert_step([-inf], -inf, [-2, inf])
     106  assert_step([], -inf, [-2, -inf])
     107  assert_step([-inf, -inf, -inf], -inf, [-2, 3], inf: true)
     108  assert_step([], -inf, [-2, -3])
     109  assert_step([-inf, -inf, -inf], -inf, [inf], inf: true)
     110  assert_step([-inf], -inf, [-inf])
     111  assert_step([-inf], -inf, [inf, inf])
     112  assert_step([], -inf, [inf, -inf])
     113  assert_step([-inf], -inf, [-inf, -inf])
     114end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/proc.rb

    r331 r439  
    1212
    1313  assert_equal (Proc.new {}).class, Proc
     14
     15  assert_raise LocalJumpError do
     16    Proc.new{ break }.call
     17  end
    1418end
    1519
     
    154158    b
    155159  end
    156   assert_equal pr.object_id, mock(&pr).object_id
     160  assert_same pr, mock(&pr)
    157161  assert_equal pr, mock(&pr)
    158162
     
    165169  assert_raise(TypeError){ mock(&(Object.new)) }
    166170end
     171
     172assert('Creation of a proc through the block of a method') do
     173  def m(&b) b end
     174
     175  assert_equal m{}.class, Proc
     176
     177  assert_raise LocalJumpError do
     178    m{ break }.call
     179  end
     180end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/range.rb

    r331 r439  
    99  assert_true (1..10) == (1..10)
    1010  assert_false (1..10) == (1..100)
     11  skip unless Object.const_defined?(:Float)
    1112  assert_true (1..10) == Range.new(1.0, 10.0)
    1213end
     
    6061  assert_false b.exclude_end?
    6162
    62   assert_raise(NameError) { (0..1).send(:initialize, 1, 3) }
     63  assert_raise(NameError) { (0..1).__send__(:initialize, 1, 3) }
    6364end
    6465
     
    9495  assert_false (1..10).eql? "1..10"
    9596end
     97
     98assert('Range#initialize_copy', '15.2.14.4.15') do
     99  assert_raise(NameError) { (0..1).__send__(:initialize_copy, 1..3) }
     100end
     101
     102assert('Range#dup') do
     103  r = (1..3).dup
     104  assert_equal 1, r.begin
     105  assert_equal 3, r.end
     106  assert_false r.exclude_end?
     107
     108  r = ("a"..."z").dup
     109  assert_equal "a", r.begin
     110  assert_equal "z", r.end
     111  assert_true r.exclude_end?
     112end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/string.rb

    r331 r439  
    33# String ISO Test
    44
    5 UTF8STRING = ("\343\201\202".size == 1)
     5UTF8STRING = __ENCODING__ == "UTF-8"
    66
    77assert('String', '15.2.10') do
     
    2121  assert_equal(-1, d)
    2222  assert_equal  1, e
     23  assert_nil 'a' <=> 1024
    2324end
    2425
     
    3738  assert_equal 'aaaaa', 'a' * 5
    3839  assert_equal '', 'a' * 0
    39   assert_raise(ArgumentError) do
    40     'a' * -1
    41   end
     40  assert_raise(ArgumentError) { 'a' * -1 }
     41  assert_raise(TypeError) { 'a' * '1' }
     42  assert_raise(TypeError) { 'a' * nil }
     43
     44  skip unless Object.const_defined?(:Float)
     45  assert_equal 'aa', 'a' * 2.1
     46  assert_raise(RangeError) { '' * 1e30 }
     47  assert_raise(RangeError) { '' * Float::INFINITY }
     48  assert_raise(RangeError) { '' * Float::NAN }
    4249end
    4350
    4451assert('String#[]', '15.2.10.5.6') do
    4552  # length of args is 1
    46   a = 'abc'[0]
    47   b = 'abc'[-1]
    48   c = 'abc'[10]
    49   d = 'abc'[-10]
    50   e = 'abc'[1.1]
     53  assert_equal 'a', 'abc'[0]
     54  assert_equal 'c', 'abc'[-1]
     55  assert_nil 'abc'[10]
     56  assert_nil 'abc'[-10]
     57  assert_equal 'b', 'abc'[1.1] if Object.const_defined?(:Float)
    5158
    5259  # length of args is 2
    53   a1 = 'abc'[0, -1]
    54   b1 = 'abc'[10, 0]
    55   c1 = 'abc'[-10, 0]
    56   d1 = 'abc'[0, 0]
    57   e1 = 'abc'[1, 2]
    58 
    59   # args is RegExp
    60   # It will be tested in mrbgems.
     60  assert_nil 'abc'[0, -1]
     61  assert_nil 'abc'[10, 0]
     62  assert_nil 'abc'[-10, 0]
     63  assert_equal '', 'abc'[0, 0]
     64  assert_equal 'bc', 'abc'[1, 2]
    6165
    6266  # args is String
    63   a3 = 'abc'['bc']
    64   b3 = 'abc'['XX']
    65 
    66   assert_equal 'a', 'a'
    67   # assert_equal 'c', b
    68   # assert_nil c
    69   # assert_nil d
    70   # assert_equal 'b', e
    71   # assert_nil a1
    72   # assert_nil b1
    73   # assert_nil c1
    74   # assert_equal '', d1
    75   # assert_equal 'bc', e1
    76   # assert_equal 'bc', a3
    77   # assert_nil b3
    78 
    79   # assert_raise(TypeError) do
    80   #   a[nil]
    81   # end
     67  assert_equal 'bc', 'abc'['bc']
     68  assert_nil 'abc'['XX']
     69
     70  assert_raise(TypeError) { 'abc'[nil] }
    8271end
    8372
     
    155144  end
    156145
    157   e = 'abc'
    158   e[1.1] = 'X'
    159   assert_equal 'aXc', e
    160 
     146  if Object.const_defined?(:Float)
     147   e = 'abc'
     148   e[1.1] = 'X'
     149   assert_equal 'aXc', e
     150  end
     151
     152  assert_raise(TypeError) { 'a'[0] = 1 }
     153  assert_raise(TypeError) { 'a'[:a] = '1' }
    161154
    162155  # length of args is 2
     
    196189    b3['XX'] = 'Y'
    197190  end
    198 end
     191
     192  assert_raise(TypeError) { 'a'[:a, 0] = '1' }
     193  assert_raise(TypeError) { 'a'[0, :a] = '1' }
     194  assert_raise(TypeError) { 'a'[0, 1] = 1 }
     195end
     196
     197assert('String[]=(UTF-8)') do
     198  a = "➀➁➂➃➄"
     199  a[3] = "⚃"
     200  assert_equal "➀➁➂⚃➄", a
     201
     202  b = "➀➁➂➃➄"
     203  b[3, 0] = "⛄"
     204  assert_equal "➀➁➂⛄➃➄", b
     205
     206  c = "➀➁➂➃➄"
     207  c[3, 2] = "⚃⚄"
     208  assert_equal "➀➁➂⚃⚄", c
     209
     210  d = "➀➁➂➃➄"
     211  d[5] = "⛄"
     212  assert_equal "➀➁➂➃➄⛄", d
     213
     214  e = "➀➁➂➃➄"
     215  e[5, 0] = "⛄"
     216  assert_equal "➀➁➂➃➄⛄", e
     217
     218  f = "➀➁➂➃➄"
     219  f[5, 2] = "⛄"
     220  assert_equal "➀➁➂➃➄⛄", f
     221
     222  g = "➀➁➂➃➄"
     223  assert_raise(IndexError) { g[6] = "⛄" }
     224
     225  h = "➀➁➂➃➄"
     226  assert_raise(IndexError) { h[6, 0] = "⛄" }
     227
     228  i = "➀➁➂➃➄"
     229  assert_raise(IndexError) { i[6, 2] = "⛄" }
     230
     231  j = "➀➁➂➃➄"
     232  j["➃"] = "⚃"
     233  assert_equal "➀➁➂⚃➄", j
     234
     235  k = "➀➁➂➃➄"
     236  assert_raise(IndexError) { k["⛄"] = "⛇" }
     237
     238  l = "➀➁➂➃➄"
     239  assert_nothing_raised { l["➂"] = "" }
     240  assert_equal "➀➁➃➄", l
     241
     242  m = "➀➁➂➃➄"
     243  assert_raise(TypeError) { m["➂"] = nil }
     244  assert_equal "➀➁➂➃➄", m
     245end if UTF8STRING
    199246
    200247assert('String#capitalize', '15.2.10.5.7') do
     
    252299end
    253300
    254 assert('String#chomp! uses the correct length') do
    255   class A
    256     def to_str
    257       $s.replace("AA")
    258       "A"
    259     end
    260   end
    261 
    262   $s = "AAA"
    263   $s.chomp!(A.new)
    264   assert_equal $s, "A"
    265 end
    266 
    267301assert('String#chop', '15.2.10.5.11') do
    268302  a = ''.chop
     
    367401  assert_equal('aBcaBc', 'abcabc'.gsub('b'){|w| w.capitalize }, 'gsub with block')
    368402  assert_equal('$a$a$',  '#a#a#'.gsub('#', '$'), 'mruby/mruby#847')
    369   assert_equal('$a$a$',  '#a#a#'.gsub('#'){|w| '$' }, 'mruby/mruby#847 with block')
     403  assert_equal('$a$a$',  '#a#a#'.gsub('#'){|_w| '$' }, 'mruby/mruby#847 with block')
    370404  assert_equal('$$a$$',  '##a##'.gsub('##', '$$'), 'mruby/mruby#847 another case')
    371   assert_equal('$$a$$',  '##a##'.gsub('##'){|w| '$$' }, 'mruby/mruby#847 another case with block')
     405  assert_equal('$$a$$',  '##a##'.gsub('##'){|_w| '$$' }, 'mruby/mruby#847 another case with block')
    372406  assert_equal('A',      'a'.gsub('a', 'A'))
    373407  assert_equal('A',      'a'.gsub('a'){|w| w.capitalize })
     
    418452  assert_equal 5, "hello".index("", 5)
    419453  assert_equal nil, "hello".index("", 6)
    420 end
     454  assert_equal 3, "hello".index("l", -2)
     455  assert_raise(ArgumentError) { "hello".index }
     456  assert_raise(TypeError) { "hello".index(101) }
     457end
     458
     459assert('String#index(UTF-8)', '15.2.10.5.22') do
     460  assert_equal 0, '⓿➊➋➌➍➎'.index('⓿')
     461  assert_nil '⓿➊➋➌➍➎'.index('➓')
     462  assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', 1)
     463  assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', -7)
     464  assert_equal 6, "⓿➊➋➌➍➎".index("", 6)
     465  assert_equal nil, "⓿➊➋➌➍➎".index("", 7)
     466  assert_equal 0, '⓿➊➋➌➍➎'.index("\xe2")
     467  assert_equal nil, '⓿➊➋➌➍➎'.index("\xe3")
     468  assert_equal 6, "\xd1\xd1\xd1\xd1\xd1\xd1⓿➊➋➌➍➎".index('⓿')
     469end if UTF8STRING
    421470
    422471assert('String#initialize', '15.2.10.5.23') do
     
    476525
    477526assert('String#reverse(UTF-8)', '15.2.10.5.29') do
    478   assert_equal "ち", "こんにちは世界"[3]
    479   assert_equal nil, "こんにちは世界"[20]
    480   assert_equal "世", "こんにちは世界"[-2]
    481   assert_equal "世界", "こんにちは世界"[-2..-1]
    482   assert_equal "んに", "こんにちは世界"[1,2]
    483   assert_equal "世", "こんにちは世界"["世"]
     527  a = 'こんにちは世界!'
     528  a.reverse
     529
     530  assert_equal 'こんにちは世界!', a
     531  assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse
     532  assert_equal 'あ', 'あ'.reverse
    484533end if UTF8STRING
    485534
     
    498547  assert_equal '!界世はちにんこ', a
    499548  assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse!
     549
     550  b = 'あ'
     551  b.reverse!
     552  assert_equal 'あ', b
    500553end if UTF8STRING
    501554
    502555assert('String#rindex', '15.2.10.5.31') do
    503556  assert_equal 0, 'abc'.rindex('a')
     557  assert_equal 0, 'abc'.rindex('a', 3)
     558  assert_nil 'abc'.rindex('a', -4)
    504559  assert_nil 'abc'.rindex('d')
     560  assert_equal 6, 'abcabc'.rindex('')
     561  assert_equal 3, 'abcabc'.rindex('a')
    505562  assert_equal 0, 'abcabc'.rindex('a', 1)
    506563  assert_equal 3, 'abcabc'.rindex('a', 4)
     564  assert_equal 0, 'abcabc'.rindex('a', -4)
     565  assert_raise(ArgumentError) { "hello".rindex }
     566  assert_raise(TypeError) { "hello".rindex(101) }
    507567end
    508568
    509569assert('String#rindex(UTF-8)', '15.2.10.5.31') do
    510570  str = "こんにちは世界!\nこんにちは世界!"
    511   assert_nil str.index('さ')
    512   assert_equal 3, str.index('ち')
    513   assert_equal 12, str.index('ち', 10)
    514   assert_equal nil, str.index("さ")
    515 end if UTF8STRING
    516 
    517 # 'String#scan', '15.2.10.5.32' will be tested in mrbgems.
     571  assert_nil str.rindex('さ')
     572  assert_equal 12, str.rindex('ち')
     573  assert_equal 3, str.rindex('ち', 10)
     574  assert_equal 3, str.rindex('ち', -6)
     575
     576  broken = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"
     577  assert_nil broken.rindex("\x81") # "\x81" is a part of "☁" ("\xe2\x98\x81")
     578  assert_equal 11, broken.rindex("☁")
     579  assert_equal 11, broken.rindex("☁", 12)
     580  assert_equal 11, broken.rindex("☁", 11)
     581  assert_equal  3, broken.rindex("☁", 10)
     582end if UTF8STRING
     583
     584# assert('String#scan', '15.2.10.5.32') do
     585#   # Not implemented yet
     586# end
    518587
    519588assert('String#size', '15.2.10.5.33') do
     
    591660  miss = str.sub("X", "Z")
    592661  assert_equal str, miss
    593   assert_not_equal str.object_id, miss.object_id
     662  assert_not_same str, miss
    594663
    595664  a = []
     
    619688
    620689assert('String#to_f', '15.2.10.5.38') do
    621   a = ''.to_f
    622   b = '123456789'.to_f
    623   c = '12345.6789'.to_f
    624   d = '1e-2147483648'.to_f
    625   e = '1e2147483648'.to_f
    626 
    627   assert_float(0.0, a)
    628   assert_float(123456789.0, b)
    629   assert_float(12345.6789, c)
    630   assert_float(0, d)
    631   assert_float(Float::INFINITY, e)
    632 end
     690  assert_operator(0.0, :eql?, ''.to_f)
     691  assert_operator(123456789.0, :eql?, '123456789'.to_f)
     692  assert_operator(12345.6789, :eql?, '12345.6789'.to_f)
     693  assert_operator(0.0, :eql?, '1e-2147483648'.to_f)
     694  assert_operator(Float::INFINITY, :eql?, '1e2147483648'.to_f)
     695  assert_operator(0.0, :eql?, 'a'.to_f)
     696  assert_operator(4.0, :eql?, '4a5'.to_f)
     697  assert_operator(12.0, :eql?, '1_2__3'.to_f)
     698  assert_operator(123.0, :eql?, '1_2_3'.to_f)
     699  assert_operator(68.0, :eql?, '68_'.to_f)
     700  assert_operator(68.0, :eql?, '68._7'.to_f)
     701  assert_operator(68.7, :eql?, '68.7_'.to_f)
     702  assert_operator(68.7, :eql?, '68.7_ '.to_f)
     703  assert_operator(6.0, :eql?, '6 8.7'.to_f)
     704  assert_operator(68.0, :eql?, '68. 7'.to_f)
     705  assert_operator(0.0, :eql?, '_68'.to_f)
     706  assert_operator(0.0, :eql?, ' _68'.to_f)
     707  assert_operator(12.34, :eql?, '1_2.3_4'.to_f)
     708  assert_operator(12.3, :eql?, '1_2.3__4'.to_f)
     709  assert_operator(0.9, :eql?, '.9'.to_f)
     710  assert_operator(0.9, :eql?, "\t\r\n\f\v .9 \t\r\n\f\v".to_f)
     711end if Object.const_defined?(:Float)
    633712
    634713assert('String#to_i', '15.2.10.5.39') do
    635   a = ''.to_i
    636   b = '32143'.to_i
    637   c = 'a'.to_i(16)
    638   d = '100'.to_i(2)
    639   e = '1_000'.to_i
    640 
    641   assert_equal 0, a
    642   assert_equal 32143, b
    643   assert_equal 10, c
    644   assert_equal 4, d
    645   assert_equal 1_000, e
     714  assert_operator 0, :eql?, ''.to_i
     715  assert_operator 32143, :eql?, '32143'.to_i
     716  assert_operator 10, :eql?, 'a'.to_i(16)
     717  assert_operator 4, :eql?, '100'.to_i(2)
     718  assert_operator 1_000, :eql?, '1_000'.to_i
     719  assert_operator 0, :eql?, 'a'.to_i
     720  assert_operator 4, :eql?, '4a5'.to_i
     721  assert_operator 12, :eql?, '1_2__3'.to_i
     722  assert_operator 123, :eql?, '1_2_3'.to_i
     723  assert_operator 68, :eql?, '68_'.to_i
     724  assert_operator 68, :eql?, '68_ '.to_i
     725  assert_operator 0, :eql?, '_68'.to_i
     726  assert_operator 0, :eql?, ' _68'.to_i
     727  assert_operator 68, :eql?, "\t\r\n\f\v 68 \t\r\n\f\v".to_i
     728  assert_operator 6, :eql?, ' 6 8 '.to_i
    646729end
    647730
     
    680763
    681764assert('String#inspect', '15.2.10.5.46') do
     765  assert_equal "\"\\x00\"", "\0".inspect
     766  assert_equal "\"foo\"", "foo".inspect
     767  if UTF8STRING
     768    assert_equal '"る"', "る".inspect
     769  else
     770    assert_equal '"\xe3\x82\x8b"', "る".inspect
     771  end
     772
    682773  # should not raise an exception - regress #1210
    683774  assert_nothing_raised do
    684   ("\1" * 100).inspect
    685   end
    686 
    687   assert_equal "\"\\000\"", "\0".inspect
     775    ("\1" * 100).inspect
     776  end
    688777end
    689778
     
    693782  a = "A" * 32
    694783  assert_equal "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:", "#{a}:"
    695 end
    696 
    697 assert('Check the usage of a NUL character') do
    698   "qqq\0ppp"
    699784end
    700785
     
    724809  str.freeze
    725810
    726   assert_raise(RuntimeError) { str.upcase! }
    727 end
     811  assert_raise(FrozenError) { str.upcase! }
     812end
     813
     814assert('String literal concatenation') do
     815  assert_equal 2, ("A" "B").size
     816  assert_equal 3, ('A' "B" 'C').size
     817  assert_equal 4, (%(A) "B#{?C}" "D").size
     818end
     819
     820assert('String#getbyte') do
     821  str1 = "hello"
     822  bytes1 = [104, 101, 108, 108, 111]
     823  assert_equal bytes1[0], str1.getbyte(0)
     824  assert_equal bytes1[-1], str1.getbyte(-1)
     825  assert_equal bytes1[6], str1.getbyte(6)
     826
     827  str2 = "\xFF"
     828  bytes2 = [0xFF]
     829  assert_equal bytes2[0], str2.getbyte(0)
     830end
     831
     832assert('String#setbyte') do
     833  str1 = "hello"
     834  h = "H".getbyte(0)
     835  str1.setbyte(0, h)
     836  assert_equal(h, str1.getbyte(0))
     837  assert_equal("Hello", str1)
     838end
     839
     840assert('String#byteslice') do
     841  str1 = "hello"
     842  str2 = "\u3042ab"  # "\xE3\x81\x82ab"
     843
     844  assert_equal("h", str1.byteslice(0))
     845  assert_equal("e", str1.byteslice(1))
     846  assert_equal(nil, str1.byteslice(5))
     847  assert_equal("o", str1.byteslice(-1))
     848  assert_equal(nil, str1.byteslice(-6))
     849  assert_equal("\xE3", str2.byteslice(0))
     850  assert_equal("\x81", str2.byteslice(1))
     851  assert_equal(nil, str2.byteslice(5))
     852  assert_equal("b", str2.byteslice(-1))
     853  assert_equal(nil, str2.byteslice(-6))
     854
     855  assert_equal("", str1.byteslice(0, 0))
     856  assert_equal(str1, str1.byteslice(0, 6))
     857  assert_equal("el", str1.byteslice(1, 2))
     858  assert_equal("", str1.byteslice(5, 1))
     859  assert_equal("o", str1.byteslice(-1, 6))
     860  assert_equal(nil, str1.byteslice(-6, 1))
     861  assert_equal(nil, str1.byteslice(0, -1))
     862  assert_equal("", str2.byteslice(0, 0))
     863  assert_equal(str2, str2.byteslice(0, 6))
     864  assert_equal("\x81\x82", str2.byteslice(1, 2))
     865  assert_equal("", str2.byteslice(5, 1))
     866  assert_equal("b", str2.byteslice(-1, 6))
     867  assert_equal(nil, str2.byteslice(-6, 1))
     868  assert_equal(nil, str2.byteslice(0, -1))
     869
     870  assert_equal("ell", str1.byteslice(1..3))
     871  assert_equal("el", str1.byteslice(1...3))
     872  assert_equal("h", str1.byteslice(0..0))
     873  assert_equal("", str1.byteslice(5..0))
     874  assert_equal("o", str1.byteslice(4..5))
     875  assert_equal(nil, str1.byteslice(6..0))
     876  assert_equal("", str1.byteslice(-1..0))
     877  assert_equal("llo", str1.byteslice(-3..5))
     878  assert_equal("\x81\x82a", str2.byteslice(1..3))
     879  assert_equal("\x81\x82", str2.byteslice(1...3))
     880  assert_equal("\xE3", str2.byteslice(0..0))
     881  assert_equal("", str2.byteslice(5..0))
     882  assert_equal("b", str2.byteslice(4..5))
     883  assert_equal(nil, str2.byteslice(6..0))
     884  assert_equal("", str2.byteslice(-1..0))
     885  assert_equal("\x82ab", str2.byteslice(-3..5))
     886
     887  assert_raise(ArgumentError) { str1.byteslice }
     888  assert_raise(ArgumentError) { str1.byteslice(1, 2, 3) }
     889  assert_raise(TypeError) { str1.byteslice("1") }
     890  assert_raise(TypeError) { str1.byteslice("1", 2) }
     891  assert_raise(TypeError) { str1.byteslice(1, "2") }
     892  assert_raise(TypeError) { str1.byteslice(1..2, 3) }
     893
     894  skip unless Object.const_defined?(:Float)
     895  assert_equal("o", str1.byteslice(4.0))
     896  assert_equal("\x82ab", str2.byteslice(2.0, 3.0))
     897end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/superclass.rb

    r321 r439  
    2424  [:StandardError, :Exception, '15.2.23.2'],
    2525  [:ArgumentError, :StandardError, '15.2.24.2'],
    26   [:LocalJumpError, :StandardError, '15.2.25.2'],
     26  # [:LocalJumpError, :StandardError, '15.2.25.2'],
     27  [:LocalJumpError, :ScriptError, '15.2.25.2'], # mruby specific
    2728  [:RangeError, :StandardError, '12.2.26.2'],
    2829  [:RegexpError, :StandardError, '12.2.27.2'],
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/symbol.rb

    r331 r439  
    1414
    1515assert('Symbol#===', '15.2.11.3.1') do
    16   assert_true :abc == :abc
    17   assert_false :abc == :cba
     16  assert_true :abc === :abc
     17  assert_false :abc === :cba
    1818end
    1919
     
    2929  assert_equal :abc, :abc.to_sym
    3030end
     31
     32assert('Symbol#to_proc') do
     33  assert_equal 5, :abs.to_proc[-5]
     34end
  • EcnlProtoTool/trunk/mruby-2.1.1/test/t/syntax.rb

    r331 r439  
    404404    assert_equal ['test', 'test dynamic `', 'test', 'test dynamic `'], results
    405405
     406    results = []
     407    assert_equal 'test sym test sym test', `test #{:sym} test #{:sym} test`
     408
    406409    alias_method sym, :old_cmd
    407410  end
     
    421424
    422425assert('method definition in cmdarg') do
    423   if false
     426  result = class MethodDefinitionInCmdarg
     427    def self.bar(arg); arg end
    424428    bar def foo; self.each do end end
    425429  end
    426   true
     430  assert_equal(:foo, result)
    427431end
    428432
     
    448452end
    449453
     454assert('local variable definition in default value and subsequent arguments') do
     455  def m(a = b = 1, c) [a, b, c] end
     456  assert_equal([1, 1, :c], m(:c))
     457  assert_equal([:a, nil, :c], m(:a, :c))
     458
     459  def m(a = b = 1, &c) [a, b, c ? true : nil] end
     460  assert_equal([1, 1, nil], m)
     461  assert_equal([1, 1, true], m{})
     462  assert_equal([:a, nil, nil], m(:a))
     463  assert_equal([:a, nil, true], m(:a){})
     464end
     465
    450466assert('multiline comments work correctly') do
    451467=begin
    452468this is a comment with nothing after begin and end
    453469=end
    454 =begin  this is a comment 
     470=begin  this is a comment
    455471this is a comment with extra after =begin
    456472=end
    457473=begin
    458474this is a comment that has =end with spaces after it
    459 =end 
     475=end
    460476=begin this is a comment
    461477this is a comment that has extra after =begin and =end with spaces after it
    462 =end 
     478=end
    463479  line = __LINE__
    464480=begin  this is a comment
     
    467483  assert_equal(line + 4, __LINE__)
    468484end
     485
     486assert 'keyword arguments' do
     487  def m(a, b:1) [a, b] end
     488  assert_equal [1, 1], m(1)
     489  assert_equal [1, 2], m(1, b: 2)
     490
     491  def m(a, b:) [a, b] end
     492  assert_equal [1, 2], m(1, b: 2)
     493  assert_raise(ArgumentError) { m b: 1 }
     494  assert_raise(ArgumentError) { m 1 }
     495
     496  def m(a:) a end
     497  assert_equal 1, m(a: 1)
     498  assert_raise(ArgumentError) { m }
     499  assert_raise(ArgumentError) { m 'a'  => 1, a: 1 }
     500  h = { a: 1 }
     501  assert_equal 1, m(h)
     502  assert_equal({ a: 1 }, h)
     503
     504  def m(a: 1) a end
     505  assert_equal 1, m
     506  assert_equal 2, m(a: 2)
     507  assert_raise(ArgumentError) { m 1 }
     508
     509  def m(**) end
     510  assert_nil m
     511  assert_nil m a: 1, b: 2
     512  assert_raise(ArgumentError) { m 2 }
     513
     514  def m(a, **) a end
     515  assert_equal 1, m(1)
     516  assert_equal 1, m(1, a: 2, b: 3)
     517  assert_equal({ 'a' => 1, b: 2 }, m('a' => 1, b: 2))
     518
     519  def m(a, **k) [a, k] end
     520  assert_equal [1, {}], m(1)
     521  assert_equal [1, {a: 2, b: 3}], m(1, a: 2, b: 3)
     522  assert_equal [{'a' => 1, b: 2}, {}], m('a' => 1, b: 2)
     523
     524  def m(a=1, **) a end
     525  assert_equal 1, m
     526  assert_equal 2, m(2, a: 1, b: 0)
     527  assert_raise(ArgumentError) { m('a' => 1, a: 2) }
     528
     529  def m(a=1, **k) [a, k] end
     530  assert_equal [1, {}], m
     531  assert_equal [1, {a: 1}], m(a: 1)
     532  assert_equal [2, {a: 1, b: 2}], m(2, a: 1, b: 2)
     533  assert_equal [{a: 1}, {b: 2}], m({a: 1}, {b: 2})
     534
     535  def m(*, a:) a end
     536  assert_equal 1, m(a: 1)
     537  assert_equal 3, m(1, 2, a: 3)
     538  assert_raise(ArgumentError) { m('a' => 1, a: 2) }
     539
     540  def m(*a, b:) [a, b] end
     541  assert_equal [[], 1], m(b: 1)
     542  assert_equal [[1, 2], 3], m(1, 2, b: 3)
     543  assert_raise(ArgumentError) { m('a' => 1, b: 2) }
     544
     545  def m(*a, b: 1) [a, b] end
     546  assert_equal [[], 1], m
     547  assert_equal [[1, 2, 3], 4], m(1, 2, 3, b: 4)
     548  assert_raise(ArgumentError) { m('a' => 1, b: 2) }
     549
     550  def m(*, **) end
     551  assert_nil m()
     552  assert_nil m(a: 1, b: 2)
     553  assert_nil m(1, 2, 3, a: 4, b: 5)
     554
     555  def m(*a, **) a end
     556  assert_equal [], m()
     557  assert_equal [1, 2, 3], m(1, 2, 3, a: 4, b: 5)
     558  assert_raise(ArgumentError) { m("a" => 1, a: 1) }
     559  assert_equal [1], m(1, **{a: 2})
     560
     561  def m(*, **k) k end
     562  assert_equal({}, m())
     563  assert_equal({a: 4, b: 5}, m(1, 2, 3, a: 4, b: 5))
     564  assert_raise(ArgumentError) { m("a" => 1, a: 1) }
     565
     566  def m(a = nil, b = nil, **k) [a, k] end
     567  assert_equal [nil, {}], m()
     568  assert_equal([nil, {a: 1}], m(a: 1))
     569  assert_raise(ArgumentError) { m("a" => 1, a: 1) }
     570  assert_equal([{"a" => 1}, {a: 1}], m({ "a" => 1 }, a: 1))
     571  assert_equal([{a: 1}, {}], m({a: 1}, {}))
     572  assert_equal([nil, {}], m({}))
     573
     574  def m(*a, **k) [a, k] end
     575  assert_equal([[], {}], m())
     576  assert_equal([[1], {}], m(1))
     577  assert_equal([[], {a: 1, b: 2}], m(a: 1, b: 2))
     578  assert_equal([[1, 2, 3], {a: 2}], m(1, 2, 3, a: 2))
     579  assert_raise(ArgumentError) { m("a" => 1, a: 1) }
     580  assert_raise(ArgumentError) { m("a" => 1) }
     581  assert_equal([[], {a: 1}], m(a: 1))
     582  assert_raise(ArgumentError) { m("a" => 1, a: 1) }
     583  assert_equal([[{"a" => 1}], {a: 1}], m({ "a" => 1 }, a: 1))
     584  assert_equal([[{a: 1}], {}], m({a: 1}, {}))
     585  assert_raise(ArgumentError) { m({a: 1}, {"a" => 1}) }
     586
     587  def m(a:, b:) [a, b] end
     588  assert_equal([1, 2], m(a: 1, b: 2))
     589  assert_raise(ArgumentError) { m("a" => 1, a: 1, b: 2) }
     590
     591  def m(a:, b: 1) [a, b] end
     592  assert_equal([1, 1], m(a: 1))
     593  assert_equal([1, 2], m(a: 1, b: 2))
     594  assert_raise(ArgumentError) { m("a" => 1, a: 1, b: 2) }
     595
     596  def m(a:, **) a end
     597  assert_equal(1, m(a: 1))
     598  assert_equal(1, m(a: 1, b: 2))
     599  assert_raise(ArgumentError) { m("a" => 1, a: 1, b: 2) }
     600
     601  def m(a:, **k) [a, k] end
     602  assert_equal([1, {}], m(a: 1))
     603  assert_equal([1, {b: 2, c: 3}], m(a: 1, b: 2, c: 3))
     604  assert_raise(ArgumentError) { m("a" => 1, a: 1, b: 2) }
     605
     606=begin
     607  def m(a:, &b) [a, b] end
     608  assert_equal([1, nil], m(a: 1))
     609  assert_equal([1, l], m(a: 1, &(l = ->{})))
     610=end
     611
     612  def m(a: 1, b:) [a, b] end
     613  assert_equal([1, 0], m(b: 0))
     614  assert_equal([3, 2], m(b: 2, a: 3))
     615  assert_raise(ArgumentError) { m a: 1 }
     616
     617  def m(a: def m(a: 1) a end, b:)
     618    [a, b]
     619  end
     620  assert_equal([2, 3], m(a: 2, b: 3))
     621  assert_equal([:m, 1], m(b: 1))
     622  # Note the default value of a: in the original method.
     623  assert_equal(1, m())
     624
     625  def m(a: 1, b: 2) [a, b] end
     626  assert_equal([1, 2], m())
     627  assert_equal([4, 3], m(b: 3, a: 4))
     628
     629  def m(a: 1, **) a end
     630  assert_equal(1, m())
     631  assert_equal(2, m(a: 2, b: 1))
     632
     633  def m(a: 1, **k) [a, k] end
     634  assert_equal([1, {b: 2, c: 3}], m(b: 2, c: 3))
     635
     636  def m(a:, **) yield end
     637  assert_raise(ArgumentError) { m { :blk } }
     638  assert_equal :blk, m(a: 1){ :blk }
     639
     640  def m(a:, **k, &b) [b.call, k] end
     641  assert_raise(ArgumentError) { m { :blk } }
     642  assert_equal [:blk, {b: 2}], m(a: 1, b: 2){ :blk }
     643
     644  def m(**k, &b) [k, b] end
     645  assert_equal([{ a: 1, b: 2}, nil], m(a: 1, b: 2))
     646  assert_equal :blk, m{ :blk }[1].call
     647
     648  def m(hsh = {}) hsh end
     649  assert_equal({ a: 1, b: 2 }, m(a: 1, b: 2))
     650  assert_equal({ a: 1, 'b' => 2 }, m(a: 1, 'b' => 2))
     651
     652  def m(hsh) hsh end
     653  assert_equal({ a: 1, b: 2 }, m(a: 1, b: 2))
     654  assert_equal({ a: 1, 'b' => 2 }, m(a: 1, 'b' => 2))
     655
     656=begin
     657  def m(a, b=1, *c, (*d, (e)), f: 2, g:, h:, **k, &l)
     658    [a, b, c, d, e, f, g, h, k, l]
     659  end
     660  result = m(9, 8, 7, 6, f: 5, g: 4, h: 3, &(l = ->{}))
     661  assert_equal([9, 8, [7], [], 6, 5, 4, 3, {}, l], result)
     662
     663  def m a, b=1, *c, d, e:, f: 2, g:, **k, &l
     664    [a, b, c, d, e, f, g, k, l]
     665  end
     666  result = m(1, 2, e: 3, g: 4, h: 5, i: 6, &(l = ->{}))
     667  assert_equal([1, 1, [], 2, 3, 2, 4, { h: 5, i: 6 }, l], result)
     668=end
     669
     670  def m(a: b = 1, c:) [a, b, c] end
     671  assert_equal([1, 1, :c], m(c: :c))
     672  assert_equal([:a, nil, :c], m(a: :a, c: :c))
     673end
     674
     675assert('numbered parameters') do
     676  assert_equal(15, [1,2,3,4,5].reduce {_1+_2})
     677  assert_equal(45, Proc.new do _1 + _2 + _3 + _4 + _5 + _6 + _7 + _8 + _9 end.call(*[1, 2, 3, 4, 5, 6, 7, 8, 9]))
     678end
     679
     680assert('_0 is not numbered parameter') do
     681  _0 = :l
     682  assert_equal(:l, ->{_0}.call)
     683end
  • EcnlProtoTool/trunk/mruby-2.1.1/travis_config.rb

    r321 r439  
    1 MRuby::Build.new('debug') do |conf|
     1MRuby::Build.new('full-debug') do |conf|
    22  toolchain :gcc
    33  enable_debug
     
    66  conf.gembox 'full-core'
    77  conf.cc.flags += %w(-Werror=declaration-after-statement)
    8   conf.compilers.each do |c|
    9     c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA)
    10   end
    11 
    12   build_mrbc_exec
    13 end
    14 
    15 MRuby::Build.new('full-debug') do |conf|
    16   toolchain :gcc
    17   enable_debug
    18 
    19   # include all core GEMs
    20   conf.gembox 'full-core'
    21   conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
     8  conf.cc.defines += %w(MRB_GC_STRESS MRB_METHOD_CACHE MRB_ENABLE_DEBUG_HOOK)
    229
    2310  conf.enable_test
     
    4128
    4229  conf.gembox 'full-core'
    43   conf.cc.flags += %w(-Werror=declaration-after-statement)
     30  conf.cc.flags += %w(-fpermissive)
    4431  conf.compilers.each do |c|
    4532    c.defines += %w(MRB_GC_FIXED_ARENA)
Note: See TracChangeset for help on using the changeset viewer.