jitcraft/Interpreter.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 03 00:25:29 2012 -0700 (2012-07-03)
changeset 30 8c8bf75114f7
parent 28 a9665857cfd5
child 39 158f476b92b3
permissions -rw-r--r--
Remove calls to ZONE().
dvander@0
     1
/*
dvander@0
     2
 * Copyright (C) 2012 David Anderson
dvander@0
     3
 *
dvander@0
     4
 * This file is part of JITCraft.
dvander@0
     5
 *
dvander@0
     6
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@0
     7
 * the terms of the GNU General Public License as published by the Free
dvander@0
     8
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@0
     9
 * any later version.
dvander@0
    10
 * 
dvander@0
    11
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@0
    12
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@0
    13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@0
    14
 *
dvander@0
    15
 * You should have received a copy of the GNU General Public License along with
dvander@0
    16
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@0
    17
 */
dvander@0
    18
#include "Interpreter.h"
dvander@0
    19
#include "Modules.h"
dvander@0
    20
#include "Zone.h"
dvander@0
    21
#include "Types.h"
dvander@12
    22
#include "Array.h"
dvander@14
    23
#include "Reference.h"
dvander@28
    24
#include "Heap-inl.h"
dvander@0
    25
dvander@0
    26
using namespace jc;
dvander@0
    27
dvander@0
    28
#define PUSH_I32(top, value)    \
dvander@0
    29
    do {                        \
dvander@0
    30
        top.sp->i32 = value;    \
dvander@0
    31
        top.sp++;               \
dvander@0
    32
   } while (0)
dvander@0
    33
dvander@4
    34
#define PUSH_F(top, value)      \
dvander@4
    35
    do {                        \
dvander@4
    36
        top.sp->f = value;      \
dvander@4
    37
        top.sp++;               \
dvander@4
    38
   } while (0)
dvander@4
    39
dvander@0
    40
static inline int
dvander@0
    41
POP_I32(Top &top)
dvander@0
    42
{
dvander@0
    43
    int value = top.sp[-1].i32;
dvander@0
    44
    top.sp--;
dvander@0
    45
    return value;
dvander@0
    46
}
dvander@0
    47
dvander@4
    48
static inline float
dvander@4
    49
POP_F(Top &top)
dvander@4
    50
{
dvander@4
    51
    float value = top.sp[-1].f;
dvander@4
    52
    top.sp--;
dvander@4
    53
    return value;
dvander@4
    54
}
dvander@4
    55
dvander@0
    56
static inline bool
dvander@14
    57
PushNewRef(Zone *zone, Top &top, void *location, Heap::Tenure tenure)
dvander@14
    58
{
dvander@14
    59
    Reference *ref = Reference::NewStack(zone, location, tenure);
dvander@14
    60
    if (!ref)
dvander@14
    61
        return false;
dvander@14
    62
    top.sp->ref = ref;
dvander@14
    63
    top.sp++;
dvander@14
    64
    return true;
dvander@14
    65
}
dvander@14
    66
dvander@14
    67
static inline bool
dvander@0
    68
CheckDimensionSize(int size, unsigned width)
dvander@0
    69
{
dvander@0
    70
    if (size <= 0) {
dvander@0
    71
        assert(false);
dvander@0
    72
        return false;
dvander@0
    73
    }
dvander@0
    74
    // One  word, because we hide stuff below and need to add that in.
dvander@0
    75
    if (unsigned(size) >= (INT_MAX / width) - sizeof(unsigned)) {
dvander@0
    76
        assert(false);
dvander@0
    77
        return false;
dvander@0
    78
    }
dvander@0
    79
    return true;
dvander@0
    80
}
dvander@0
    81
dvander@12
    82
// Generate an array with completely static sizes.
dvander@12
    83
static Array *
dvander@27
    84
GenerateArray(Zone *zone, Handle<ArrayMap> map)
dvander@0
    85
{
dvander@12
    86
    assert(map->type()->elements() != -1);
dvander@0
    87
dvander@12
    88
    // :TODO: use Local
dvander@12
    89
    Array *array = Array::New(zone, map, map->type()->elements(), Heap::Tenure_Stack);
dvander@12
    90
    if (!array)
dvander@0
    91
        return NULL;
dvander@0
    92
dvander@12
    93
    if (map->type()->levels() == 1)
dvander@12
    94
        return array;
dvander@0
    95
dvander@27
    96
    Local<ArrayMap> contained(zone, map->contained());
dvander@12
    97
    for (unsigned i = 0; i < unsigned(map->type()->elements()); i++) {
dvander@27
    98
        Array *sub = GenerateArray(zone, contained);
dvander@12
    99
        if (!sub)
dvander@0
   100
            return NULL;
dvander@12
   101
        array->writeObject(zone, i, sub);
dvander@0
   102
    }
dvander@0
   103
dvander@12
   104
    return array;
dvander@0
   105
}
dvander@0
   106
dvander@21
   107
static bool
dvander@21
   108
CopyArray(Zone *zone, Array *source, Array *dest)
dvander@21
   109
{
dvander@21
   110
    assert(source->type()->levels() == 1);
dvander@21
   111
    assert(dest->type()->levels() == 1);
dvander@21
   112
    assert(source->type()->contained()->primitive() ==
dvander@21
   113
           dest->type()->contained()->primitive());
dvander@21
   114
    assert(source->nelements() >= dest->nelements());
dvander@21
   115
    assert(dest->elementSize() == source->elementSize());
dvander@21
   116
dvander@21
   117
    memcpy(source->vec(), dest->vec(), dest->nelements() * dest->elementSize());
dvander@21
   118
    return true;
dvander@21
   119
}
dvander@21
   120
dvander@0
   121
bool
dvander@4
   122
jc::Interpret(Frame *frame, LocalSlot *result)
dvander@0
   123
{
dvander@0
   124
    Top &top = *ZONE()->stack().top();
dvander@0
   125
    LocalSlot *locals = frame->locals();
dvander@0
   126
dvander@0
   127
    for (;;) {
dvander@0
   128
        Opcode op = Opcode(*top.pc);
dvander@0
   129
        switch (op) {
dvander@0
   130
dvander@0
   131
case OP_NOP:
dvander@0
   132
    break;
dvander@0
   133
dvander@0
   134
case OP_INT:
dvander@0
   135
    PUSH_I32(top, READ_INT32(top.pc));
dvander@0
   136
    break;
dvander@0
   137
dvander@4
   138
case OP_FLOAT:
dvander@4
   139
    PUSH_F(top, READ_FLOAT(top.pc));
dvander@4
   140
    break;
dvander@4
   141
dvander@0
   142
case OP_RETURN:
dvander@0
   143
{
dvander@4
   144
    *result = *--top.sp;
dvander@4
   145
    if (!frame->prev())
dvander@0
   146
        return true;
dvander@0
   147
dvander@0
   148
    frame = ZONE()->stack().popFrame(frame);
dvander@0
   149
    locals = frame->locals();
dvander@4
   150
    *top.sp++ = *result;
dvander@0
   151
    top.pc += OpcodeInfo[*top.pc].length;
dvander@0
   152
    continue;
dvander@0
   153
}
dvander@0
   154
dvander@0
   155
#define RELATIONAL_JUMP(op)                 \
dvander@0
   156
    {                                       \
dvander@0
   157
        int right = POP_I32(top);           \
dvander@0
   158
        int left = POP_I32(top);            \
dvander@0
   159
        if (left op right) {                \
dvander@0
   160
            top.pc += READ_INT32(top.pc);   \
dvander@0
   161
            continue;                       \
dvander@0
   162
        }                                   \
dvander@0
   163
    }
dvander@0
   164
dvander@0
   165
case OP_JL:
dvander@0
   166
    RELATIONAL_JUMP(<);
dvander@0
   167
    break;
dvander@0
   168
dvander@0
   169
case OP_JLE:
dvander@0
   170
    RELATIONAL_JUMP(<=);
dvander@0
   171
    break;
dvander@0
   172
dvander@0
   173
case OP_JG:
dvander@0
   174
    RELATIONAL_JUMP(>);
dvander@0
   175
    break;
dvander@0
   176
dvander@0
   177
case OP_JGE:
dvander@0
   178
    RELATIONAL_JUMP(>=);
dvander@0
   179
    break;
dvander@0
   180
dvander@0
   181
case OP_JEQ:
dvander@0
   182
    RELATIONAL_JUMP(==);
dvander@0
   183
    break;
dvander@0
   184
dvander@0
   185
case OP_JNE:
dvander@0
   186
    RELATIONAL_JUMP(!=);
dvander@0
   187
    break;
dvander@0
   188
dvander@0
   189
case OP_JT:
dvander@0
   190
{
dvander@0
   191
    int value = POP_I32(top);
dvander@0
   192
    if (value) {
dvander@0
   193
        top.pc += READ_INT32(top.pc);
dvander@0
   194
        continue;
dvander@0
   195
    }
dvander@0
   196
    break;
dvander@0
   197
}
dvander@0
   198
dvander@0
   199
case OP_JF:
dvander@0
   200
{
dvander@0
   201
    int value = POP_I32(top);
dvander@0
   202
    if (!value) {
dvander@0
   203
        top.pc += READ_INT32(top.pc);
dvander@0
   204
        continue;
dvander@0
   205
    }
dvander@0
   206
    break;
dvander@0
   207
}
dvander@0
   208
dvander@0
   209
case OP_JUMP:
dvander@0
   210
    top.pc += READ_INT32(top.pc);
dvander@0
   211
    continue;
dvander@0
   212
dvander@0
   213
case OP_GETLOCAL:
dvander@0
   214
{
dvander@0
   215
    int slot = READ_INT32(top.pc);
dvander@0
   216
    *top.sp++ = locals[slot];
dvander@0
   217
    break;
dvander@0
   218
}
dvander@0
   219
dvander@0
   220
case OP_SETLOCAL:
dvander@0
   221
{
dvander@0
   222
    int slot = READ_INT32(top.pc);
dvander@0
   223
    locals[slot] = top.sp[-1];
dvander@0
   224
    break;
dvander@0
   225
}
dvander@0
   226
dvander@0
   227
case OP_ADD:
dvander@0
   228
{
dvander@0
   229
    int right = POP_I32(top);
dvander@0
   230
    int left = POP_I32(top);
dvander@0
   231
    int result = left + right;
dvander@0
   232
    PUSH_I32(top, result);
dvander@0
   233
    break;
dvander@0
   234
}
dvander@0
   235
dvander@0
   236
case OP_SUB:
dvander@0
   237
{
dvander@0
   238
    int right = POP_I32(top);
dvander@0
   239
    int left = POP_I32(top);
dvander@0
   240
    int result = left - right;
dvander@0
   241
    PUSH_I32(top, result);
dvander@0
   242
    break;
dvander@0
   243
}
dvander@0
   244
dvander@0
   245
case OP_MUL:
dvander@0
   246
{
dvander@0
   247
    int right = POP_I32(top);
dvander@0
   248
    int left = POP_I32(top);
dvander@0
   249
    int result = left * right;
dvander@22
   250
    PUSH_I32(top, result);
dvander@0
   251
    break;
dvander@0
   252
}
dvander@0
   253
dvander@0
   254
case OP_DIV:
dvander@0
   255
{
dvander@0
   256
    int right = POP_I32(top);
dvander@0
   257
    int left = POP_I32(top);
dvander@0
   258
    if (!right)
dvander@0
   259
        return false;
dvander@0
   260
    int result = left / right;
dvander@0
   261
    PUSH_I32(top, result);
dvander@0
   262
    break;
dvander@0
   263
}
dvander@0
   264
dvander@4
   265
case OP_ADD_F:
dvander@4
   266
{
dvander@4
   267
    float right = POP_F(top);
dvander@4
   268
    float left = POP_F(top);
dvander@4
   269
    float result = left + right;
dvander@4
   270
    PUSH_F(top, result);
dvander@4
   271
    break;
dvander@4
   272
}
dvander@4
   273
dvander@4
   274
case OP_SUB_F:
dvander@4
   275
{
dvander@4
   276
    float right = POP_F(top);
dvander@4
   277
    float left = POP_F(top);
dvander@4
   278
    float result = left - right;
dvander@4
   279
    PUSH_F(top, result);
dvander@4
   280
    break;
dvander@4
   281
}
dvander@4
   282
dvander@4
   283
case OP_MUL_F:
dvander@4
   284
{
dvander@4
   285
    float right = POP_F(top);
dvander@4
   286
    float left = POP_F(top);
dvander@4
   287
    float result = left * right;
dvander@4
   288
    PUSH_F(top, result);
dvander@4
   289
    break;
dvander@4
   290
}
dvander@4
   291
dvander@4
   292
case OP_DIV_F:
dvander@4
   293
{
dvander@4
   294
    float right = POP_F(top);
dvander@4
   295
    float left = POP_F(top);
dvander@4
   296
    if (!right)
dvander@4
   297
        return false;
dvander@4
   298
    float result = left / right;
dvander@4
   299
    PUSH_F(top, result);
dvander@4
   300
    break;
dvander@4
   301
}
dvander@4
   302
dvander@8
   303
case OP_SHL:
dvander@8
   304
{
dvander@8
   305
    int right = POP_I32(top);
dvander@8
   306
    int left = POP_I32(top);
dvander@8
   307
    int result = left << right;
dvander@8
   308
    PUSH_I32(top, result);
dvander@8
   309
    break;
dvander@8
   310
}
dvander@8
   311
dvander@8
   312
case OP_SHR:
dvander@8
   313
{
dvander@8
   314
    int right = POP_I32(top);
dvander@8
   315
    int left = POP_I32(top);
dvander@8
   316
    int result = left >> right;
dvander@8
   317
    PUSH_I32(top, result);
dvander@8
   318
    break;
dvander@8
   319
}
dvander@8
   320
dvander@8
   321
case OP_USHR:
dvander@8
   322
{
dvander@8
   323
    int right = POP_I32(top);
dvander@8
   324
    int left = POP_I32(top);
dvander@8
   325
    int result = unsigned(left) >> unsigned(right);
dvander@8
   326
    PUSH_I32(top, result);
dvander@8
   327
    break;
dvander@8
   328
}
dvander@8
   329
dvander@8
   330
case OP_BITAND:
dvander@8
   331
{
dvander@8
   332
    int right = POP_I32(top);
dvander@8
   333
    int left = POP_I32(top);
dvander@8
   334
    int result = left & right;
dvander@8
   335
    PUSH_I32(top, result);
dvander@8
   336
    break;
dvander@8
   337
}
dvander@8
   338
dvander@8
   339
case OP_BITOR:
dvander@8
   340
{
dvander@8
   341
    int right = POP_I32(top);
dvander@8
   342
    int left = POP_I32(top);
dvander@8
   343
    int result = left | right;
dvander@8
   344
    PUSH_I32(top, result);
dvander@8
   345
    break;
dvander@8
   346
}
dvander@8
   347
dvander@8
   348
case OP_BITXOR:
dvander@8
   349
{
dvander@8
   350
    int right = POP_I32(top);
dvander@8
   351
    int left = POP_I32(top);
dvander@8
   352
    int result = left ^ right;
dvander@8
   353
    PUSH_I32(top, result);
dvander@8
   354
    break;
dvander@8
   355
}
dvander@8
   356
dvander@0
   357
case OP_POP:
dvander@0
   358
    top.sp--;
dvander@0
   359
    break;
dvander@0
   360
dvander@0
   361
case OP_STOP:
dvander@0
   362
    assert(false);
dvander@0
   363
    break;
dvander@0
   364
dvander@0
   365
case OP_CALLGLOBAL:
dvander@0
   366
{
dvander@0
   367
    unsigned argc = READ_UINT32(top.pc);
dvander@0
   368
    unsigned index = READ_UINT32(top.pc + 4);
dvander@26
   369
    Function *newFun = frame->code()->module()->getFunction(index);
dvander@26
   370
    frame = ZONE()->stack().pushFrame(frame, newFun);
dvander@0
   371
    assert(frame);
dvander@26
   372
    assert(newFun->nargs() == argc);
dvander@0
   373
dvander@0
   374
    locals = frame->locals();
dvander@0
   375
    continue;
dvander@0
   376
}
dvander@0
   377
dvander@0
   378
case OP_GETARG:
dvander@0
   379
{
dvander@0
   380
    unsigned slot = READ_UINT32(top.pc);
dvander@0
   381
    *top.sp++ = frame->arg(slot);
dvander@0
   382
    break;
dvander@0
   383
}
dvander@0
   384
dvander@0
   385
case OP_SETARG:
dvander@0
   386
{
dvander@0
   387
    unsigned slot = READ_UINT32(top.pc);
dvander@0
   388
    frame->arg(slot) = *--top.sp;
dvander@0
   389
    break;
dvander@0
   390
}
dvander@0
   391
dvander@19
   392
case OP_BOUNDS:
dvander@0
   393
{
dvander@12
   394
    Array *array = top.sp[-2].array;
dvander@0
   395
    int index = top.sp[-1].i32;
dvander@12
   396
    if (index < 0 || unsigned(index) >= array->nelements())
dvander@0
   397
        return false;
dvander@0
   398
    break;
dvander@0
   399
}
dvander@0
   400
dvander@6
   401
case OP_GETARRAY_I:
dvander@0
   402
{
dvander@12
   403
    Array *array = top.sp[-2].array;
dvander@0
   404
    int index = top.sp[-1].i32;
dvander@0
   405
    top.sp[-2].i32 = array->readInt32(index);
dvander@0
   406
    top.sp--;
dvander@0
   407
    break;
dvander@0
   408
}
dvander@0
   409
dvander@7
   410
case OP_GETARRAY_F:
dvander@7
   411
{
dvander@12
   412
    Array *array = top.sp[-2].array;
dvander@7
   413
    int index = top.sp[-1].i32;
dvander@7
   414
    top.sp[-2].f = array->readFloat(index);
dvander@7
   415
    top.sp--;
dvander@7
   416
    break;
dvander@7
   417
}
dvander@7
   418
dvander@21
   419
case OP_GETARRAY_C:
dvander@21
   420
{
dvander@21
   421
    Array *array = top.sp[-2].array;
dvander@21
   422
    int index = top.sp[-1].i32;
dvander@21
   423
    top.sp[-2].i32 = array->readChar(index);
dvander@21
   424
    top.sp--;
dvander@21
   425
    break;
dvander@21
   426
}
dvander@21
   427
dvander@6
   428
case OP_SETARRAY_I:
dvander@0
   429
{
dvander@12
   430
    Array *array = top.sp[-3].array;
dvander@0
   431
    int index = top.sp[-2].i32;
dvander@0
   432
    array->writeInt32(index, top.sp[-1].i32);
dvander@0
   433
    top.sp[-3] = top.sp[-1];
dvander@0
   434
    top.sp -= 2;
dvander@0
   435
    break;
dvander@0
   436
}
dvander@0
   437
dvander@7
   438
case OP_SETARRAY_F:
dvander@7
   439
{
dvander@12
   440
    Array *array = top.sp[-3].array;
dvander@7
   441
    int index = top.sp[-2].i32;
dvander@7
   442
    array->writeFloat(index, top.sp[-1].f);
dvander@7
   443
    top.sp[-3] = top.sp[-1];
dvander@7
   444
    top.sp -= 2;
dvander@7
   445
    break;
dvander@7
   446
}
dvander@7
   447
dvander@21
   448
case OP_SETARRAY_C:
dvander@21
   449
{
dvander@21
   450
    Array *array = top.sp[-3].array;
dvander@21
   451
    int index = top.sp[-2].i32;
dvander@21
   452
    array->writeChar(index, top.sp[-1].i32);
dvander@21
   453
    top.sp[-3] = top.sp[-1];
dvander@21
   454
    top.sp -= 2;
dvander@21
   455
    break;
dvander@21
   456
}
dvander@21
   457
dvander@19
   458
case OP_GETARRAY_O:
dvander@0
   459
{
dvander@12
   460
    Array *array = top.sp[-2].array;
dvander@0
   461
    int index = top.sp[-1].i32;
dvander@12
   462
    top.sp[-2].array = Array::cast(array->readObject(index));
dvander@0
   463
    top.sp--;
dvander@0
   464
    break;
dvander@0
   465
}
dvander@0
   466
dvander@4
   467
case OP_CVT_I2F:
dvander@4
   468
{
dvander@4
   469
    int ival = POP_I32(top);
dvander@4
   470
    float fval = (float)ival;
dvander@4
   471
    PUSH_F(top, fval);
dvander@4
   472
    break;
dvander@4
   473
}
dvander@4
   474
dvander@19
   475
case OP_NEWARRAY_LIFO:
dvander@12
   476
{
dvander@12
   477
    // :TODO: use Local
dvander@27
   478
    Local<ArrayMap> map(ZONE(), ArrayMap::cast(frame->code()->map(READ_UINT32(top.pc))));
dvander@12
   479
    Array *array = GenerateArray(ZONE(), map);
dvander@12
   480
    if (!array) {
dvander@12
   481
        assert(false);
dvander@12
   482
        return false;
dvander@12
   483
    }
dvander@12
   484
    top.sp->obj = array;
dvander@12
   485
    top.sp++;
dvander@12
   486
    break;
dvander@12
   487
}
dvander@12
   488
dvander@12
   489
case OP_SAVELIFO:
dvander@10
   490
{
dvander@10
   491
    unsigned slot = READ_UINT32(top.pc);
dvander@12
   492
    locals[slot].address = ZONE()->heap().lifoPosition();
dvander@12
   493
    break;
dvander@12
   494
}
dvander@12
   495
dvander@12
   496
case OP_UNWINDLIFO:
dvander@12
   497
{
dvander@12
   498
    unsigned slot = READ_UINT32(top.pc);
dvander@12
   499
    ZONE()->heap().unwindLifo(locals[slot].address);
dvander@10
   500
    break;
dvander@10
   501
}
dvander@10
   502
dvander@14
   503
case OP_VARREF_LIFO:
dvander@14
   504
{
dvander@14
   505
    unsigned slot = READ_UINT32(top.pc);
dvander@14
   506
    if (!PushNewRef(ZONE(), top, &locals[slot], Heap::Tenure_Stack)) {
dvander@14
   507
        assert(false);
dvander@14
   508
        return false;
dvander@14
   509
    }
dvander@14
   510
    break;
dvander@14
   511
}
dvander@14
   512
dvander@14
   513
case OP_ARGREF_LIFO:
dvander@14
   514
{
dvander@14
   515
    unsigned slot = READ_UINT32(top.pc);
dvander@14
   516
    if (!PushNewRef(ZONE(), top, &frame->arg(slot), Heap::Tenure_Stack)) {
dvander@14
   517
        assert(false);
dvander@14
   518
        return false;
dvander@14
   519
    }
dvander@14
   520
    break;
dvander@14
   521
}
dvander@14
   522
dvander@17
   523
case OP_ARRAYREF_LIFO:
dvander@17
   524
{
dvander@17
   525
    Reference *ref = Reference::NewArray(ZONE(), top.sp[-2].array, top.sp[-1].i32, Heap::Tenure_Stack);
dvander@17
   526
    if (!ref) {
dvander@17
   527
        assert(false);
dvander@17
   528
        return false;
dvander@17
   529
    }
dvander@17
   530
    top.sp[-2].ref = ref;
dvander@17
   531
    top.sp--;
dvander@17
   532
    break;
dvander@17
   533
}
dvander@17
   534
dvander@16
   535
case OP_SLOTREF_LIFO:
dvander@16
   536
{
dvander@17
   537
    Reference *ref = Reference::NewStack(ZONE(), top.sp[-1], Heap::Tenure_Stack);
dvander@16
   538
    if (!ref) {
dvander@16
   539
        assert(false);
dvander@16
   540
        return false;
dvander@16
   541
    }
dvander@16
   542
    top.sp[-1].ref = ref;
dvander@16
   543
    break;
dvander@16
   544
}
dvander@16
   545
dvander@14
   546
case OP_GETREF_I:
dvander@14
   547
{
dvander@14
   548
    top.sp[-1].i32 = top.sp[-1].ref->getInt();
dvander@14
   549
    break;
dvander@14
   550
}
dvander@14
   551
dvander@14
   552
case OP_SETREF_I:
dvander@14
   553
{
dvander@14
   554
    top.sp[-2].ref->setInt(top.sp[-1].i32);
dvander@14
   555
    top.sp[-2].i32 = top.sp[-1].i32;
dvander@23
   556
    top.sp--;
dvander@14
   557
    break;
dvander@14
   558
}
dvander@14
   559
dvander@14
   560
case OP_GETREF_F:
dvander@14
   561
{
dvander@14
   562
    top.sp[-1].f = top.sp[-1].ref->getFloat();
dvander@14
   563
    break;
dvander@14
   564
}
dvander@14
   565
dvander@14
   566
case OP_SETREF_F:
dvander@14
   567
{
dvander@14
   568
    top.sp[-2].ref->setFloat(top.sp[-1].f);
dvander@14
   569
    top.sp[-2].f = top.sp[-1].f;
dvander@14
   570
    break;
dvander@14
   571
}
dvander@14
   572
dvander@21
   573
case OP_OBJECT:
dvander@21
   574
{
dvander@21
   575
    top.sp->obj = frame->code()->object(READ_UINT32(top.pc));
dvander@21
   576
    top.sp++;
dvander@21
   577
    break;
dvander@21
   578
}
dvander@21
   579
dvander@21
   580
case OP_ARRAYCOPY:
dvander@21
   581
{
dvander@21
   582
    // Note for this assignment opcode, we return the left-hand side, not the
dvander@21
   583
    // right, since in this case the result of the expression could be different.
dvander@21
   584
    if (!CopyArray(ZONE(), top.sp[-2].array, top.sp[-1].array)) {
dvander@21
   585
        assert(false);
dvander@21
   586
        return false;
dvander@21
   587
    }
dvander@21
   588
    top.sp--;
dvander@21
   589
    break;
dvander@21
   590
}
dvander@21
   591
dvander@22
   592
case OP_DUP:
dvander@22
   593
{
dvander@23
   594
    top.sp++;
dvander@23
   595
    top.sp[-1] = top.sp[-2];
dvander@22
   596
    break;
dvander@22
   597
}
dvander@22
   598
dvander@22
   599
case OP_DUP2:
dvander@22
   600
{
dvander@23
   601
    top.sp += 2;
dvander@23
   602
    top.sp[-2] = top.sp[-4];
dvander@23
   603
    top.sp[-1] = top.sp[-3];
dvander@23
   604
    break;
dvander@23
   605
}
dvander@23
   606
dvander@23
   607
case OP_SWAP:
dvander@23
   608
{
dvander@23
   609
    LocalSlot slot = top.sp[-2];
dvander@23
   610
    top.sp[-2] = top.sp[-1];
dvander@23
   611
    top.sp[-1] = slot;
dvander@23
   612
    break;
dvander@23
   613
}
dvander@23
   614
dvander@23
   615
case OP_ROLL3:
dvander@23
   616
{
dvander@23
   617
    LocalSlot slot = top.sp[-3];
dvander@23
   618
    top.sp[-3] = top.sp[-2];
dvander@23
   619
    top.sp[-2] = top.sp[-1];
dvander@23
   620
    top.sp[-1] = slot;
dvander@23
   621
    break;
dvander@23
   622
}
dvander@23
   623
dvander@23
   624
case OP_PICK2:
dvander@23
   625
{
dvander@23
   626
    top.sp++;
dvander@23
   627
    top.sp[-1] = top.sp[-3];
dvander@23
   628
    break;
dvander@23
   629
}
dvander@23
   630
dvander@23
   631
case OP_PICK3:
dvander@23
   632
{
dvander@23
   633
    top.sp++;
dvander@23
   634
    top.sp[-1] = top.sp[-4];
dvander@22
   635
    break;
dvander@22
   636
}
dvander@22
   637
dvander@0
   638
default:
dvander@0
   639
    assert(false);
dvander@0
   640
    return false;
dvander@0
   641
dvander@0
   642
        }
dvander@0
   643
dvander@0
   644
        top.pc += OpcodeInfo[op].length;
dvander@0
   645
    }
dvander@0
   646
dvander@0
   647
    return true;
dvander@0
   648
}