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