Added full comparator support.
Added full comparator support.
1.1 --- a/jitcraft/BytecodeCompiler.cpp Sun Jul 15 14:40:11 2012 -0700
1.2 +++ b/jitcraft/BytecodeCompiler.cpp Sun Jul 15 19:48:15 2012 -0700
1.3 @@ -95,6 +95,18 @@
1.4 return OP_BITAND;
1.5 case TOK_BITOR:
1.6 return OP_BITOR;
1.7 + case TOK_GT:
1.8 + return OP_GT;
1.9 + case TOK_GE:
1.10 + return OP_GE;
1.11 + case TOK_LT:
1.12 + return OP_LT;
1.13 + case TOK_LE:
1.14 + return OP_LE;
1.15 + case TOK_EQUALS:
1.16 + return OP_EQ;
1.17 + case TOK_NOTEQUALS:
1.18 + return OP_NE;
1.19 default:
1.20 assert(kind == TOK_BITXOR);
1.21 return OP_BITXOR;
1.22 @@ -380,11 +392,23 @@
1.23 assert(needed->primitive() == node->type()->primitive());
1.24 }
1.25
1.26 +static inline Type *
1.27 +GetCoercionType(TokenKind tok, Type *left, Type *right)
1.28 +{
1.29 + if (left->isFloat())
1.30 + return left;
1.31 + return right;
1.32 +}
1.33 +
1.34 void
1.35 BytecodeCompiler::visit(BinaryExpression *node)
1.36 {
1.37 - visitForALU(node->type(), node->left());
1.38 - visitForALU(node->type(), node->right());
1.39 + Local<Type> leftType(zone_, node->left()->type());
1.40 + Local<Type> rightType(zone_, node->right()->type());
1.41 + Local<Type> coerce(zone_, GetCoercionType(node->token(), leftType, rightType));
1.42 +
1.43 + visitForALU(coerce, node->left());
1.44 + visitForALU(coerce, node->right());
1.45
1.46 Opcode op = TokenToOpcode(node->token());
1.47 if (node->type()->isFloat())
1.48 @@ -425,10 +449,12 @@
1.49 TokenKind token = ToCompare(expression);
1.50 if (token == TOK_EOF) {
1.51 expression->accept(this);
1.52 - if (onTrue)
1.53 - __ j(OP_JT, label);
1.54 - else
1.55 - __ j(OP_JF, label);
1.56 +
1.57 + Opcode op = (onTrue) ? OP_JT : OP_JF;
1.58 + if (expression->type()->isFloat())
1.59 + op = (Opcode)(int(op) + (OP_JL_F - OP_JL));
1.60 +
1.61 + __ j(op, label);
1.62 return;
1.63 }
1.64
1.65 @@ -438,8 +464,15 @@
1.66
1.67 assert(expression->isBinaryExpression());
1.68 BinaryExpression *binary = expression->toBinaryExpression();
1.69 - binary->left()->accept(this);
1.70 - binary->right()->accept(this);
1.71 + Local<Type> leftType(zone_, binary->left()->type());
1.72 + Local<Type> rightType(zone_, binary->right()->type());
1.73 + Local<Type> coerce(zone_, GetCoercionType(binary->token(), leftType, rightType));
1.74 +
1.75 + visitForALU(coerce, binary->left());
1.76 + visitForALU(coerce, binary->right());
1.77 + if (coerce->isFloat())
1.78 + op = (Opcode)(int(op) + (OP_JL_F - OP_JL));
1.79 +
1.80 __ j(op, label);
1.81 }
1.82
2.1 --- a/jitcraft/Interpreter.cpp Sun Jul 15 14:40:11 2012 -0700
2.2 +++ b/jitcraft/Interpreter.cpp Sun Jul 15 19:48:15 2012 -0700
2.3 @@ -235,6 +235,8 @@
2.4 RELATIONAL_JUMP(!=);
2.5 break;
2.6
2.7 +#undef RELATIONAL_JUMP
2.8 +
2.9 case OP_JT:
2.10 {
2.11 int value = POP_I32(top);
2.12 @@ -255,6 +257,60 @@
2.13 break;
2.14 }
2.15
2.16 +#define RELATIONAL_JUMP_F(op) \
2.17 + { \
2.18 + float right = POP_F(top); \
2.19 + float left = POP_F(top); \
2.20 + if (left op right) { \
2.21 + top.pc += READ_INT32(top.pc); \
2.22 + continue; \
2.23 + } \
2.24 + }
2.25 +
2.26 +case OP_JL_F:
2.27 + RELATIONAL_JUMP_F(<);
2.28 + break;
2.29 +
2.30 +case OP_JLE_F:
2.31 + RELATIONAL_JUMP_F(<=);
2.32 + break;
2.33 +
2.34 +case OP_JG_F:
2.35 + RELATIONAL_JUMP_F(>);
2.36 + break;
2.37 +
2.38 +case OP_JGE_F:
2.39 + RELATIONAL_JUMP_F(>=);
2.40 + break;
2.41 +
2.42 +case OP_JEQ_F:
2.43 + RELATIONAL_JUMP_F(==);
2.44 + break;
2.45 +
2.46 +case OP_JNE_F:
2.47 + RELATIONAL_JUMP_F(!=);
2.48 + break;
2.49 +
2.50 +case OP_JT_F:
2.51 +{
2.52 + float value = POP_F(top);
2.53 + if (value) {
2.54 + top.pc += READ_INT32(top.pc);
2.55 + continue;
2.56 + }
2.57 + break;
2.58 +}
2.59 +
2.60 +case OP_JF_F:
2.61 +{
2.62 + float value = POP_F(top);
2.63 + if (!value) {
2.64 + top.pc += READ_INT32(top.pc);
2.65 + continue;
2.66 + }
2.67 + break;
2.68 +}
2.69 +
2.70 case OP_JUMP:
2.71 top.pc += READ_INT32(top.pc);
2.72 continue;
2.73 @@ -313,6 +369,48 @@
2.74 break;
2.75 }
2.76
2.77 +case OP_LT:
2.78 +{
2.79 + top.sp[-2].i32 = top.sp[-2].i32 < top.sp[-1].i32;
2.80 + top.sp--;
2.81 + break;
2.82 +}
2.83 +
2.84 +case OP_LE:
2.85 +{
2.86 + top.sp[-2].i32 = top.sp[-2].i32 <= top.sp[-1].i32;
2.87 + top.sp--;
2.88 + break;
2.89 +}
2.90 +
2.91 +case OP_GT:
2.92 +{
2.93 + top.sp[-2].i32 = top.sp[-2].i32 > top.sp[-1].i32;
2.94 + top.sp--;
2.95 + break;
2.96 +}
2.97 +
2.98 +case OP_GE:
2.99 +{
2.100 + top.sp[-2].i32 = top.sp[-2].i32 >= top.sp[-1].i32;
2.101 + top.sp--;
2.102 + break;
2.103 +}
2.104 +
2.105 +case OP_EQ:
2.106 +{
2.107 + top.sp[-2].i32 = (top.sp[-2].i32 == top.sp[-1].i32);
2.108 + top.sp--;
2.109 + break;
2.110 +}
2.111 +
2.112 +case OP_NE:
2.113 +{
2.114 + top.sp[-2].i32 = (top.sp[-2].i32 != top.sp[-1].i32);
2.115 + top.sp--;
2.116 + break;
2.117 +}
2.118 +
2.119 case OP_ADD_F:
2.120 {
2.121 float right = POP_F(top);
2.122 @@ -349,6 +447,48 @@
2.123 break;
2.124 }
2.125
2.126 +case OP_LT_F:
2.127 +{
2.128 + top.sp[-2].f = top.sp[-2].f < top.sp[-1].f;
2.129 + top.sp--;
2.130 + break;
2.131 +}
2.132 +
2.133 +case OP_LE_F:
2.134 +{
2.135 + top.sp[-2].f = top.sp[-2].f <= top.sp[-1].f;
2.136 + top.sp--;
2.137 + break;
2.138 +}
2.139 +
2.140 +case OP_GT_F:
2.141 +{
2.142 + top.sp[-2].f = top.sp[-2].f > top.sp[-1].f;
2.143 + top.sp--;
2.144 + break;
2.145 +}
2.146 +
2.147 +case OP_GE_F:
2.148 +{
2.149 + top.sp[-2].f = top.sp[-2].f >= top.sp[-1].f;
2.150 + top.sp--;
2.151 + break;
2.152 +}
2.153 +
2.154 +case OP_EQ_F:
2.155 +{
2.156 + top.sp[-2].i32 = (top.sp[-2].f == top.sp[-1].f);
2.157 + top.sp--;
2.158 + break;
2.159 +}
2.160 +
2.161 +case OP_NE_F:
2.162 +{
2.163 + top.sp[-2].i32 = (top.sp[-2].f != top.sp[-1].f);
2.164 + top.sp--;
2.165 + break;
2.166 +}
2.167 +
2.168 case OP_SHL:
2.169 {
2.170 int right = POP_I32(top);
3.1 --- a/jitcraft/Opcodes.cpp Sun Jul 15 14:40:11 2012 -0700
3.2 +++ b/jitcraft/Opcodes.cpp Sun Jul 15 19:48:15 2012 -0700
3.3 @@ -186,6 +186,18 @@
3.4 case OP_PICK3:
3.5 case OP_CALL:
3.6 case OP_MODULE:
3.7 + case OP_LT:
3.8 + case OP_LE:
3.9 + case OP_GE:
3.10 + case OP_GT:
3.11 + case OP_EQ:
3.12 + case OP_NE:
3.13 + case OP_LT_F:
3.14 + case OP_LE_F:
3.15 + case OP_GE_F:
3.16 + case OP_GT_F:
3.17 + case OP_EQ_F:
3.18 + case OP_NE_F:
3.19 break;
3.20
3.21 case OP_STOP:
3.22 @@ -208,6 +220,14 @@
3.23 case OP_JNE:
3.24 case OP_JT:
3.25 case OP_JF:
3.26 + case OP_JL_F:
3.27 + case OP_JLE_F:
3.28 + case OP_JG_F:
3.29 + case OP_JGE_F:
3.30 + case OP_JEQ_F:
3.31 + case OP_JNE_F:
3.32 + case OP_JT_F:
3.33 + case OP_JF_F:
3.34 case OP_JUMP:
3.35 fprintf(fp, "%u (%+d)", unsigned((pc + READ_INT32(pc)) - code->start()), READ_INT32(pc));
3.36 break;
4.1 --- a/jitcraft/Opcodes.tbl Sun Jul 15 14:40:11 2012 -0700
4.2 +++ b/jitcraft/Opcodes.tbl Sun Jul 15 19:48:15 2012 -0700
4.3 @@ -52,56 +52,72 @@
4.4 OPDEF(OP_JT, 9, "jt", 5, 1, 0)
4.5 OPDEF(OP_JF, 10, "jf", 5, 1, 0)
4.6
4.7 +OPDEF(OP_JL_F, 11, "jl.f", 5, 2, 0)
4.8 +OPDEF(OP_JLE_F, 12, "jle.f", 5, 2, 0)
4.9 +OPDEF(OP_JG_F, 13, "jg.f", 5, 2, 0)
4.10 +OPDEF(OP_JGE_F, 14, "jge.f", 5, 2, 0)
4.11 +OPDEF(OP_JEQ_F, 15, "jeq.f", 5, 2, 0)
4.12 +OPDEF(OP_JNE_F, 16, "jne.f", 5, 2, 0)
4.13 +OPDEF(OP_JT_F, 17, "jt.f", 5, 1, 0)
4.14 +OPDEF(OP_JF_F, 18, "jf.f", 5, 1, 0)
4.15 +
4.16 // Unconditional jump.
4.17 -OPDEF(OP_JUMP, 11, "jump", 5, 0, 0)
4.18 +OPDEF(OP_JUMP, 19, "jump", 5, 0, 0)
4.19
4.20 // Gets or sets the value of a local variable onto the stack. The local
4.21 // variable is given by an immediate index.
4.22 -OPDEF(OP_GETLOCAL, 12, "getlocal", 5, 0, 1)
4.23 -OPDEF(OP_SETLOCAL, 13, "setlocal", 5, 1, 1)
4.24 +OPDEF(OP_GETLOCAL, 20, "getlocal", 5, 0, 1)
4.25 +OPDEF(OP_SETLOCAL, 21, "setlocal", 5, 1, 1)
4.26
4.27 // Stack transitions for these binary operators:
4.28 // rhs = pop()
4.29 // lhs = pop()
4.30 // push(lhs OP rhs)
4.31 -OPDEF(OP_ADD, 14, "add", 1, 2, 1)
4.32 -OPDEF(OP_SUB, 15, "sub", 1, 2, 1)
4.33 -OPDEF(OP_MUL, 16, "mul", 1, 2, 1)
4.34 -OPDEF(OP_DIV, 17, "div", 1, 2, 1)
4.35 +OPDEF(OP_ADD, 22, "add", 1, 2, 1)
4.36 +OPDEF(OP_SUB, 23, "sub", 1, 2, 1)
4.37 +OPDEF(OP_MUL, 24, "mul", 1, 2, 1)
4.38 +OPDEF(OP_DIV, 25, "div", 1, 2, 1)
4.39
4.40 -OPDEF(OP_POP, 18, "pop", 1, 1, 0)
4.41 +OPDEF(OP_LT, 26, "lt", 1, 2, 1)
4.42 +OPDEF(OP_LE, 27, "le", 1, 2, 1)
4.43 +OPDEF(OP_GE, 28, "ge", 1, 2, 1)
4.44 +OPDEF(OP_GT, 29, "gt", 1, 2, 1)
4.45 +OPDEF(OP_EQ, 30, "eq", 1, 2, 1)
4.46 +OPDEF(OP_NE, 31, "ne", 1, 2, 1)
4.47 +
4.48 +OPDEF(OP_POP, 32, "pop", 1, 1, 0)
4.49
4.50 // Unconditional terminator placed at the end of code. If a function returns
4.51 // void, this acts as a RETURNVOID. Otherwise, it must be unreachable.
4.52 -OPDEF(OP_STOP, 19, "stop", 1, 0, 0)
4.53 +OPDEF(OP_STOP, 33, "stop", 1, 0, 0)
4.54
4.55 // Call a function with N arguments. The target function must be the last item
4.56 // on the stack.
4.57 -OPDEF(OP_CALL, 20, "call", 1, -1, 1)
4.58 +OPDEF(OP_CALL, 34, "call", 1, -1, 1)
4.59
4.60 // Similar to GET/LOCAL, except for arguments.
4.61 -OPDEF(OP_GETARG, 21, "getarg", 5, 0, 1)
4.62 -OPDEF(OP_SETARG, 22, "setarg", 5, 1, 1)
4.63 +OPDEF(OP_GETARG, 35, "getarg", 5, 0, 1)
4.64 +OPDEF(OP_SETARG, 36, "setarg", 5, 1, 1)
4.65
4.66 // Reads or writes an integer element to an unsafe array.
4.67 // index = pop()
4.68 // ref = pop()
4.69 // ref[index]
4.70 //
4.71 -OPDEF(OP_GETARRAY_I, 23, "getarray.i", 1, 2, 1)
4.72 -OPDEF(OP_SETARRAY_I, 24, "setarray.i", 1, 3, 1)
4.73 -OPDEF(OP_GETARRAY_F, 25, "getarray.f", 1, 2, 1)
4.74 -OPDEF(OP_SETARRAY_F, 26, "setarray.f", 1, 3, 1)
4.75 -OPDEF(OP_GETARRAY_C, 27, "getarray.c", 1, 2, 1)
4.76 -OPDEF(OP_SETARRAY_C, 28, "setarray.c", 1, 3, 1)
4.77 -OPDEF(OP_GETARRAY_O, 29, "getarray.o", 1, 2, 1)
4.78 +OPDEF(OP_GETARRAY_I, 37, "getarray.i", 1, 2, 1)
4.79 +OPDEF(OP_SETARRAY_I, 38, "setarray.i", 1, 3, 1)
4.80 +OPDEF(OP_GETARRAY_F, 39, "getarray.f", 1, 2, 1)
4.81 +OPDEF(OP_SETARRAY_F, 40, "setarray.f", 1, 3, 1)
4.82 +OPDEF(OP_GETARRAY_C, 41, "getarray.c", 1, 2, 1)
4.83 +OPDEF(OP_SETARRAY_C, 42, "setarray.c", 1, 3, 1)
4.84 +OPDEF(OP_GETARRAY_O, 43, "getarray.o", 1, 2, 1)
4.85
4.86 // Allocate an array, info LIFO space if possible. The ArrayMap to use is
4.87 // specified as an index into the script's Map table.
4.88 //
4.89 // Format:
4.90 // [u8 op] [u32 index]
4.91 -OPDEF(OP_NEWARRAY_LIFO, 30, "newarray.lifo", 5, 0, 1)
4.92 +OPDEF(OP_NEWARRAY_LIFO, 44, "newarray.lifo", 5, 0, 1)
4.93
4.94 // Performs a bounds check on an unsafe array.
4.95 //
4.96 @@ -109,63 +125,70 @@
4.97 // array = pop()
4.98 // push(array)
4.99 // push(index)
4.100 -OPDEF(OP_BOUNDS, 31, "bounds", 1, 2, 2)
4.101 +OPDEF(OP_BOUNDS, 45, "bounds", 1, 2, 2)
4.102
4.103 // Pushes a 32-bit IEEE-754 floating point immediate onto the stack.
4.104 -OPDEF(OP_FLOAT, 32, "float", 5, 0, 1)
4.105 +OPDEF(OP_FLOAT, 46, "float", 5, 0, 1)
4.106
4.107 // Converts an integer to a 32-bit IEEE-754 floating point immediate.
4.108 -OPDEF(OP_CVT_I2F, 33, "cvt.i2f", 1, 1, 1)
4.109 +OPDEF(OP_CVT_I2F, 47, "cvt.i2f", 1, 1, 1)
4.110
4.111 // Stack transitions for these binary operators:
4.112 // rhs = pop()
4.113 // lhs = pop()
4.114 // push(lhs OP rhs)
4.115 -OPDEF(OP_ADD_F, 34, "add.f", 1, 2, 1)
4.116 -OPDEF(OP_SUB_F, 35, "sub.f", 1, 2, 1)
4.117 -OPDEF(OP_MUL_F, 36, "mul.f", 1, 2, 1)
4.118 -OPDEF(OP_DIV_F, 37, "div.f", 1, 2, 1)
4.119 +OPDEF(OP_ADD_F, 48, "add.f", 1, 2, 1)
4.120 +OPDEF(OP_SUB_F, 49, "sub.f", 1, 2, 1)
4.121 +OPDEF(OP_MUL_F, 50, "mul.f", 1, 2, 1)
4.122 +OPDEF(OP_DIV_F, 51, "div.f", 1, 2, 1)
4.123 +
4.124 +OPDEF(OP_LT_F, 52, "lt.f", 1, 2, 1)
4.125 +OPDEF(OP_LE_F, 53, "le.f", 1, 2, 1)
4.126 +OPDEF(OP_GE_F, 54, "ge.f", 1, 2, 1)
4.127 +OPDEF(OP_GT_F, 55, "gt.f", 1, 2, 1)
4.128 +OPDEF(OP_EQ_F, 56, "eq.f", 1, 2, 1)
4.129 +OPDEF(OP_NE_F, 57, "ne.f", 1, 2, 1)
4.130
4.131 // Bitwise operators.
4.132 -OPDEF(OP_SHL, 38, "shl", 1, 2, 1)
4.133 -OPDEF(OP_SHR, 39, "shr", 1, 2, 1)
4.134 -OPDEF(OP_USHR, 40, "ushr", 1, 2, 1)
4.135 -OPDEF(OP_BITAND, 41, "bitand", 1, 2, 1)
4.136 -OPDEF(OP_BITOR, 42, "bitor", 1, 2, 1)
4.137 -OPDEF(OP_BITXOR, 43, "bitxor", 1, 2, 1)
4.138 +OPDEF(OP_SHL, 58, "shl", 1, 2, 1)
4.139 +OPDEF(OP_SHR, 59, "shr", 1, 2, 1)
4.140 +OPDEF(OP_USHR, 60, "ushr", 1, 2, 1)
4.141 +OPDEF(OP_BITAND, 61, "bitand", 1, 2, 1)
4.142 +OPDEF(OP_BITOR, 62, "bitor", 1, 2, 1)
4.143 +OPDEF(OP_BITXOR, 63, "bitxor", 1, 2, 1)
4.144
4.145 // Saves or restores the position of the LIFO heap to/from a local slot.
4.146 -OPDEF(OP_SAVELIFO, 44, "savelifo", 5, 0, 0)
4.147 -OPDEF(OP_UNWINDLIFO, 45, "unwindlifo", 5, 0, 0)
4.148 +OPDEF(OP_SAVELIFO, 64, "savelifo", 5, 0, 0)
4.149 +OPDEF(OP_UNWINDLIFO, 65, "unwindlifo", 5, 0, 0)
4.150
4.151 // Composes a variable reference to a stack slot or argument.
4.152 -OPDEF(OP_VARREF_LIFO, 46, "varref.lifo", 5, 0, 1)
4.153 -OPDEF(OP_ARGREF_LIFO, 47, "argref.lifo", 5, 0, 1)
4.154 -OPDEF(OP_SLOTREF_LIFO, 48, "slotref.lifo", 1, 1, 1)
4.155 -OPDEF(OP_ARRAYREF_LIFO, 49, "arrayref.lifo",1, 2, 1)
4.156 -OPDEF(OP_GETREF_I, 50, "getref.i", 1, 1, 1)
4.157 -OPDEF(OP_SETREF_I, 51, "setref.i", 1, 2, 1)
4.158 -OPDEF(OP_GETREF_F, 52, "getref.f", 1, 1, 1)
4.159 -OPDEF(OP_SETREF_F, 53, "setref.f", 1, 2, 1)
4.160 +OPDEF(OP_VARREF_LIFO, 66, "varref.lifo", 5, 0, 1)
4.161 +OPDEF(OP_ARGREF_LIFO, 67, "argref.lifo", 5, 0, 1)
4.162 +OPDEF(OP_SLOTREF_LIFO, 68, "slotref.lifo", 1, 1, 1)
4.163 +OPDEF(OP_ARRAYREF_LIFO, 69, "arrayref.lifo",1, 2, 1)
4.164 +OPDEF(OP_GETREF_I, 70, "getref.i", 1, 1, 1)
4.165 +OPDEF(OP_SETREF_I, 71, "setref.i", 1, 2, 1)
4.166 +OPDEF(OP_GETREF_F, 72, "getref.f", 1, 1, 1)
4.167 +OPDEF(OP_SETREF_F, 73, "setref.f", 1, 2, 1)
4.168
4.169 // Pushes an object reference onto the stack.
4.170 -OPDEF(OP_OBJECT, 54, "object", 5, 0, 1)
4.171 +OPDEF(OP_OBJECT, 74, "object", 5, 0, 1)
4.172
4.173 // Performs an array-to-array assignment.
4.174 // Left = pop()
4.175 // Right = pop()
4.176 // copy(Left, Right)
4.177 // push(Left)
4.178 -OPDEF(OP_ARRAYCOPY, 55, "arraycopy", 1, 2, 1)
4.179 +OPDEF(OP_ARRAYCOPY, 75, "arraycopy", 1, 2, 1)
4.180
4.181 // Duplicates the top item on the stack.
4.182 -OPDEF(OP_DUP, 56, "dup", 1, 1, 2)
4.183 +OPDEF(OP_DUP, 76, "dup", 1, 1, 2)
4.184
4.185 // Duplicates the top two items on the stack.
4.186 -OPDEF(OP_DUP2, 57, "dup2", 1, 2, 4)
4.187 +OPDEF(OP_DUP2, 77, "dup2", 1, 2, 4)
4.188
4.189 // Swaps the two items at the top of the stack.
4.190 -OPDEF(OP_SWAP, 58, "swap", 1, 2, 2)
4.191 +OPDEF(OP_SWAP, 78, "swap", 1, 2, 2)
4.192
4.193 // Roll operation is the same as Forth. It steals a value on the stack,
4.194 // shifting all stack values down, and then places the stolen value back at
4.195 @@ -175,14 +198,14 @@
4.196 // sp[-3] = sp[-2]
4.197 // sp[-2] = sp[-1]
4.198 // sp[-1] = p
4.199 -OPDEF(OP_ROLL3, 59, "roll3", 1, 3, 3)
4.200 +OPDEF(OP_ROLL3, 79, "roll3", 1, 3, 3)
4.201
4.202 // Pick operation is the same as Forth. It pushes a copy of a slot at a
4.203 // specific depth.
4.204 //
4.205 // push(sp[-n])
4.206 -OPDEF(OP_PICK2, 60, "pick2", 1, 2, 3)
4.207 -OPDEF(OP_PICK3, 61, "pick3", 1, 3, 4)
4.208 +OPDEF(OP_PICK2, 80, "pick2", 1, 2, 3)
4.209 +OPDEF(OP_PICK3, 81, "pick3", 1, 3, 4)
4.210
4.211 // Calls a native function. During the course of calling a native, arguments
4.212 // on the stack are re-pushed to match the cell-based native calling
4.213 @@ -193,14 +216,14 @@
4.214 //
4.215 // [u8 Opcode] [u32 Index] [u32 ArgCount]
4.216 //
4.217 -OPDEF(OP_CALLNATIVE, 62, "callnative", 9, -1, 1)
4.218 +OPDEF(OP_CALLNATIVE, 82, "callnative", 9, -1, 1)
4.219
4.220 // Returns from a function that does return a value.
4.221 -OPDEF(OP_RETURNVOID, 63, "returnvoid", 1, 0, 0)
4.222 +OPDEF(OP_RETURNVOID, 83, "returnvoid", 1, 0, 0)
4.223
4.224 // Loads the module of the running function.
4.225 -OPDEF(OP_MODULE, 64, "module", 1, 0, 1)
4.226 +OPDEF(OP_MODULE, 84, "module", 1, 0, 1)
4.227
4.228 // Loads a function from a module object. The operand is the slot number
4.229 // in the module.
4.230 -OPDEF(OP_GETMODULE_FN, 65, "getmodule.fn", 5, 1, 1)
4.231 +OPDEF(OP_GETMODULE_FN, 85, "getmodule.fn", 5, 1, 1)
5.1 --- a/jitcraft/Parser.cpp Sun Jul 15 14:40:11 2012 -0700
5.2 +++ b/jitcraft/Parser.cpp Sun Jul 15 19:48:15 2012 -0700
5.3 @@ -1009,6 +1009,13 @@
5.4 break;
5.5 }
5.6
5.7 + // case TOK_NEW:
5.8 + // {
5.9 + // if ((statement = variableDeclaration()) == NULL)
5.10 + // return NULL;
5.11 + // break;
5.12 + // }
5.13 +
5.14 case TOK_ENUM:
5.15 if ((statement = enum_()) == NULL)
5.16 return NULL;
6.1 --- a/jitcraft/Scanner.cpp Sun Jul 15 14:40:11 2012 -0700
6.2 +++ b/jitcraft/Scanner.cpp Sun Jul 15 19:48:15 2012 -0700
6.3 @@ -476,6 +476,13 @@
6.4 case ',': return TOK_COMMA;
6.5 case '\0': return TOK_EOF;
6.6
6.7 + case '!':
6.8 + c = getChar();
6.9 + if (c == '=')
6.10 + return TOK_NOTEQUALS;
6.11 + putChar(c);
6.12 + return TOK_NOT;
6.13 +
6.14 case '=':
6.15 c = getChar();
6.16 if (c == '=')
7.1 --- a/jitcraft/SemanticAnalysis.cpp Sun Jul 15 14:40:11 2012 -0700
7.2 +++ b/jitcraft/SemanticAnalysis.cpp Sun Jul 15 19:48:15 2012 -0700
7.3 @@ -207,6 +207,16 @@
7.4 }
7.5 }
7.6
7.7 + if (token >= TOK_EQUALS && token <= TOK_GE) {
7.8 + if ((left->isFloat() || (left->isInt32() && !left->tag())) &&
7.9 + (right->isFloat() || (right->isInt32() && !left->tag())))
7.10 + {
7.11 + return zone_->types()->getPrimitive(PrimitiveType_Int32);
7.12 + }
7.13 + binaryTypeError(node, token, left, right);
7.14 + return NULL;
7.15 + }
7.16 +
7.17 if ((!left->isInt32() || left->tag()) ||
7.18 (!right->isInt32() || right->tag()))
7.19 {
8.1 --- a/jitcraft/Token.h Sun Jul 15 14:40:11 2012 -0700
8.2 +++ b/jitcraft/Token.h Sun Jul 15 19:48:15 2012 -0700
8.3 @@ -102,6 +102,7 @@
8.4 _(GT, ">") \
8.5 _(GE, ">=") \
8.6 _(COMMA, ",") \
8.7 + _(NOT, "!") \
8.8 _(EOF, "<end-of-file>")
8.9
8.10 enum TokenKind