mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 11:58:55 +00:00
Long/Float support.
This commit is contained in:
parent
d0545ad04d
commit
f11162aae4
@ -83,7 +83,7 @@ namespace MetaData {
|
||||
bCon->addOffset(int32(mLocation - branchLocation));
|
||||
else {
|
||||
mFixupList.push_back(branchLocation);
|
||||
bCon->addLong(0);
|
||||
bCon->addOffset(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,14 +112,22 @@ public:
|
||||
|
||||
void addByte(uint8 v) { mBuffer.push_back(v); }
|
||||
|
||||
void addPointer(const void *v) { ASSERT(sizeof(void *) == sizeof(uint32)); addLong((uint32)(v)); }
|
||||
static void *getPointer(void *pc) { return (void *)getLong(pc); }
|
||||
void addPointer(const void *v) { ASSERT(sizeof(void *) == sizeof(uint32)); addUInt32((uint32)(v)); }
|
||||
static void *getPointer(void *pc) { return (void *)getUInt32(pc); }
|
||||
|
||||
// These insert the opcodes...
|
||||
void addFloat64(float64 v, size_t pos) { emitOp(eNumber, pos); mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(float64)); }
|
||||
static float64 getFloat64(void *pc) { return *((float64 *)pc); }
|
||||
|
||||
void addLong(const uint32 v) { mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint32)); }
|
||||
static uint32 getLong(void *pc) { return *((uint32 *)pc); }
|
||||
void addUInt64(const uint64 v, size_t pos) { emitOp(eUInt64, pos); mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint64)); }
|
||||
static uint64 getUInt64(void *pc) { return *((uint64 *)pc); }
|
||||
|
||||
void addInt64(const int64 v, size_t pos) { emitOp(eInt64, pos); mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(int64)); }
|
||||
static int64 getInt64(void *pc) { return *((int64 *)pc); }
|
||||
|
||||
// These don't insert opcodes...
|
||||
void addUInt32(const uint32 v) { mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint32)); }
|
||||
static uint32 getUInt32(void *pc) { return *((uint32 *)pc); }
|
||||
|
||||
void addShort(uint16 v) { mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint16)); }
|
||||
static uint16 getShort(void *pc) { return *((uint16 *)pc); }
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "world.h"
|
||||
#include "utilities.h"
|
||||
#include "js2value.h"
|
||||
#include "jslong.h"
|
||||
#include "numerics.h"
|
||||
#include "fdlibm_ns.h"
|
||||
|
||||
@ -140,6 +141,23 @@ namespace MetaData {
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Don't store as an int, even if possible, we need to retain 'longness'
|
||||
js2val JS2Engine::allocULong(uint64 x)
|
||||
{
|
||||
uint64 *p = (uint64 *)(JS2Object::alloc(sizeof(uint64)));
|
||||
*p = x;
|
||||
return ULONG_TO_JS2VAL(p);
|
||||
|
||||
}
|
||||
|
||||
// Don't store as an int, even if possible, we need to retain 'longness'
|
||||
js2val JS2Engine::allocLong(int64 x)
|
||||
{
|
||||
int64 *p = (int64 *)(JS2Object::alloc(sizeof(int64)));
|
||||
*p = x;
|
||||
return LONG_TO_JS2VAL(p);
|
||||
}
|
||||
|
||||
// Convert an integer to a string
|
||||
String *numberToString(int32 i)
|
||||
{
|
||||
@ -167,6 +185,20 @@ namespace MetaData {
|
||||
return (JS2VAL_TO_BOOLEAN(x)) ? &true_StringAtom : &false_StringAtom;
|
||||
if (JS2VAL_IS_INT(x))
|
||||
return numberToString(JS2VAL_TO_INT(x));
|
||||
if (JS2VAL_IS_LONG(x)) {
|
||||
float64 d;
|
||||
JSLL_L2D(d, *JS2VAL_TO_LONG(x));
|
||||
return numberToString(&d);
|
||||
}
|
||||
if (JS2VAL_IS_ULONG(x)) {
|
||||
float64 d;
|
||||
JSLL_UL2D(d, *JS2VAL_TO_ULONG(x));
|
||||
return numberToString(&d);
|
||||
}
|
||||
if (JS2VAL_IS_FLOAT(x)) {
|
||||
float64 d = *JS2VAL_TO_FLOAT(x);
|
||||
return numberToString(&d);
|
||||
}
|
||||
if (JS2VAL_IS_DOUBLE(x))
|
||||
return numberToString(JS2VAL_TO_DOUBLE(x));
|
||||
return toString(toPrimitive(x));
|
||||
@ -202,6 +234,45 @@ namespace MetaData {
|
||||
return toNumber(toPrimitive(x));
|
||||
}
|
||||
|
||||
// x is not a number
|
||||
js2val JS2Engine::convertValueToGeneralNumber(js2val x)
|
||||
{
|
||||
// XXX Assuming convert to float64, rather than long/ulong
|
||||
return allocNumber(toNumber(x));
|
||||
}
|
||||
|
||||
// x is a Number
|
||||
int64 JS2Engine::checkInteger(js2val x)
|
||||
{
|
||||
if (JS2VAL_IS_FLOAT(x)) {
|
||||
float64 f = *JS2VAL_TO_FLOAT(x);
|
||||
if (!JSDOUBLE_IS_FINITE(f, i))
|
||||
meta->reportError(Exception::rangeError, "Non integer", errorPos());
|
||||
int64 i;
|
||||
JSLL_D2L(i, f);
|
||||
JSLL_L2D(f, i);
|
||||
if (!=) rangeError...
|
||||
return i;
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_DOUBLE(x)) {
|
||||
float64 d = *JS2VAL_TO_DOUBLE(x);
|
||||
if (!JSDOUBLE_IS_INT(d, i))
|
||||
meta->reportError(Exception::rangeError, "Non integer", errorPos());
|
||||
return i;
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_LONG(x)) {
|
||||
JSLL_L2I(i, *JS2VAL_TO_LONG(x));
|
||||
return i;
|
||||
}
|
||||
ASSERT(JS2VAL_IS_ULONG(x));
|
||||
JSLL_UL2I(i, *JS2VAL_TO_ULONG(x));
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// x is any js2val
|
||||
float64 JS2Engine::toNumber(js2val x)
|
||||
{
|
||||
if (JS2VAL_IS_INT(x))
|
||||
@ -210,11 +281,17 @@ namespace MetaData {
|
||||
if (JS2VAL_IS_DOUBLE(x))
|
||||
return *JS2VAL_TO_DOUBLE(x);
|
||||
else
|
||||
if (JS2VAL_IS_LONG(x))
|
||||
return *JS2VAL_TO_LONG(x);
|
||||
if (JS2VAL_IS_LONG(x)) {
|
||||
float64 d;
|
||||
JSLL_L2D(d, *JS2VAL_TO_LONG(x));
|
||||
return d;
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_ULONG(x))
|
||||
return *JS2VAL_TO_ULONG(x);
|
||||
if (JS2VAL_IS_ULONG(x)) {
|
||||
float64 d;
|
||||
JSLL_UL2D(d, *JS2VAL_TO_ULONG(x));
|
||||
return d;
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_FLOAT(x))
|
||||
return *JS2VAL_TO_FLOAT(x);
|
||||
@ -222,7 +299,6 @@ namespace MetaData {
|
||||
return convertValueToDouble(x);
|
||||
}
|
||||
|
||||
|
||||
// x is not a bool
|
||||
bool JS2Engine::convertValueToBoolean(js2val x)
|
||||
{
|
||||
@ -232,9 +308,15 @@ namespace MetaData {
|
||||
return false;
|
||||
if (JS2VAL_IS_INT(x))
|
||||
return (JS2VAL_TO_INT(x) != 0);
|
||||
if (JS2VAL_IS_LONG(x) || JS2VAL_IS_ULONG(x))
|
||||
return (!JSLL_IS_ZERO(x));
|
||||
if (JS2VAL_IS_FLOAT(x)) {
|
||||
float64 xd = *JS2VAL_TO_FLOAT(x);
|
||||
return ! (JSDOUBLE_IS_POSZERO(xd) || JSDOUBLE_IS_NEGZERO(xd) || JSDOUBLE_IS_NaN(xd));
|
||||
}
|
||||
if (JS2VAL_IS_DOUBLE(x)) {
|
||||
float64 *xd = JS2VAL_TO_DOUBLE(x);
|
||||
return ! (JSDOUBLE_IS_POSZERO(*xd) || JSDOUBLE_IS_NEGZERO(*xd) || JSDOUBLE_IS_NaN(*xd));
|
||||
float64 xd = *JS2VAL_TO_DOUBLE(x);
|
||||
return ! (JSDOUBLE_IS_POSZERO(xd) || JSDOUBLE_IS_NEGZERO(xd) || JSDOUBLE_IS_NaN(xd));
|
||||
}
|
||||
if (JS2VAL_IS_STRING(x)) {
|
||||
String *str = JS2VAL_TO_STRING(x);
|
||||
@ -246,8 +328,25 @@ namespace MetaData {
|
||||
// x is not an int
|
||||
int32 JS2Engine::convertValueToInteger(js2val x)
|
||||
{
|
||||
float64 f = (JS2VAL_IS_DOUBLE(x)) ? *JS2VAL_TO_DOUBLE(x) : convertValueToDouble(x);
|
||||
return toInt32(f);
|
||||
int32 i;
|
||||
if (JS2VAL_IS_LONG(x)) {
|
||||
JSLL_L2I(i, *JS2VAL_TO_LONG(x));
|
||||
return i;
|
||||
}
|
||||
if (JS2VAL_IS_ULONG(x)) {
|
||||
JSLL_UL2I(i, *JS2VAL_TO_ULONG(x));
|
||||
return i;
|
||||
}
|
||||
if (JS2VAL_IS_FLOAT(x)) {
|
||||
float64 f = *JS2VAL_TO_FLOAT(x);
|
||||
return toInt32(f);
|
||||
}
|
||||
if (JS2VAL_IS_DOUBLE(x)) {
|
||||
float64 d = *JS2VAL_TO_DOUBLE(x);
|
||||
return toInt32(d);
|
||||
}
|
||||
float64 d = convertValueToDouble(x);
|
||||
return toInt32(d);
|
||||
}
|
||||
|
||||
int32 JS2Engine::toInt32(float64 d)
|
||||
@ -356,6 +455,8 @@ namespace MetaData {
|
||||
case eTrue:
|
||||
case eFalse:
|
||||
case eNumber:
|
||||
case eUInt64:
|
||||
case eInt64:
|
||||
case eNull:
|
||||
case eThis:
|
||||
return 1; // push literal value
|
||||
@ -515,10 +616,7 @@ namespace MetaData {
|
||||
f->bCon->mark();
|
||||
}
|
||||
for (js2val *e = execStack; (e < sp); e++) {
|
||||
if (JS2VAL_IS_OBJECT(*e)) {
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(*e);
|
||||
GCMARKOBJECT(obj)
|
||||
}
|
||||
GCMARKVALUE(*e);
|
||||
}
|
||||
JS2Object::mark(JS2VAL_TO_DOUBLE(nanValue));
|
||||
JS2Object::mark(JS2VAL_TO_DOUBLE(posInfValue));
|
||||
@ -534,6 +632,6 @@ namespace MetaData {
|
||||
GCMARKVALUE(indexVal);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -74,6 +74,8 @@ enum JS2Op {
|
||||
eFalse,
|
||||
eNull,
|
||||
eNumber,
|
||||
eUInt64,
|
||||
eInt64,
|
||||
eString, // <string pointer:u32>
|
||||
eThis,
|
||||
eNewObject, // <argCount:u16>
|
||||
@ -149,20 +151,24 @@ public:
|
||||
uint32 toUInt32(float64 f);
|
||||
uint16 toUInt16(float64 f);
|
||||
|
||||
|
||||
String *convertValueToString(js2val x);
|
||||
js2val convertValueToPrimitive(js2val x);
|
||||
float64 convertValueToDouble(js2val x);
|
||||
bool convertValueToBoolean(js2val x);
|
||||
int32 convertValueToInteger(js2val x);
|
||||
js2val convertValueToGeneralNumber(js2val x);
|
||||
|
||||
String *toString(js2val x) { if (JS2VAL_IS_STRING(x)) return JS2VAL_TO_STRING(x); else return convertValueToString(x); }
|
||||
js2val toPrimitive(js2val x) { if (JS2VAL_IS_PRIMITIVE(x)) return x; else return convertValueToPrimitive(x); }
|
||||
float64 toNumber(js2val x);
|
||||
js2val toGeneralNumber(js2val x){ if (JS2VAL_IS_NUMBER(x)) return x; else return convertValueToGeneralNumber(x); }
|
||||
bool toBoolean(js2val x) { if (JS2VAL_IS_BOOLEAN(x)) return JS2VAL_TO_BOOLEAN(x); else return convertValueToBoolean(x); }
|
||||
int32 toInteger(js2val x) { if (JS2VAL_IS_INT(x)) return JS2VAL_TO_INT(x); else return convertValueToInteger(x); }
|
||||
|
||||
js2val assignmentConversion(js2val val, JS2Class *type) { return val; } // XXX s'more code, please
|
||||
|
||||
int32 checkInteger(js2val x);
|
||||
|
||||
JS2Metadata *meta;
|
||||
|
||||
@ -176,11 +182,18 @@ public:
|
||||
js2val posInfValue;
|
||||
js2val negInfValue;
|
||||
|
||||
// A cache of f.p. values (XXX experimentally trying to reduce # of double pointers XXX)
|
||||
float64 *float64Table[256];
|
||||
js2val allocNumber(float64 x);
|
||||
js2val pushNumber(float64 x) { js2val retval = allocNumber(x); push(retval); return retval; }
|
||||
|
||||
js2val allocULong(uint64 x);
|
||||
js2val pushULong(uint64 x) { js2val retval = allocULong(x); push(retval); return retval; }
|
||||
|
||||
js2val allocLong(int64 x);
|
||||
js2val pushLong(int64 x) { js2val retval = allocLong(x); push(retval); return retval; }
|
||||
|
||||
private:
|
||||
// A cache of f.p. values (XXX experimentally trying to reduce # of double pointers XXX)
|
||||
float64 *float64Table[256];
|
||||
float64 *newDoubleValue(float64 x);
|
||||
js2val retval;
|
||||
|
||||
|
@ -1087,6 +1087,7 @@ namespace MetaData {
|
||||
switch (p->getKind()) {
|
||||
case ExprNode::Null:
|
||||
case ExprNode::number:
|
||||
case ExprNode::numUnit:
|
||||
case ExprNode::string:
|
||||
case ExprNode::boolean:
|
||||
break;
|
||||
@ -1487,6 +1488,18 @@ doUnary:
|
||||
bCon->emitOp(eNull, p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::numUnit:
|
||||
{
|
||||
NumUnitExprNode *n = checked_cast<NumUnitExprNode *>(p);
|
||||
if (n->str == L"UL")
|
||||
bCon->addUInt64(n->num, p->pos);
|
||||
else
|
||||
if (n->str == L"L")
|
||||
bCon->addInt64(n->num, p->pos);
|
||||
else
|
||||
reportError(Exception::badValueError, "Unrecognized unit", p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::number:
|
||||
{
|
||||
bCon->addFloat64(checked_cast<NumberExprNode *>(p)->value, p->pos);
|
||||
@ -3149,11 +3162,11 @@ deleteClassProperty:
|
||||
if (slots) {
|
||||
ASSERT(type);
|
||||
for (uint32 i = 0; (i < type->slotCount); i++) {
|
||||
GCMARKVALUE(slots[i].value)
|
||||
GCMARKVALUE(slots[i].value);
|
||||
}
|
||||
}
|
||||
for (DynamicPropertyIterator i = dynamicProperties.begin(), end = dynamicProperties.end(); (i != end); i++) {
|
||||
GCMARKVALUE(i->second)
|
||||
GCMARKVALUE(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3195,7 +3208,7 @@ deleteClassProperty:
|
||||
if (slots) {
|
||||
ASSERT(type);
|
||||
for (uint32 i = 0; (i < type->slotCount); i++) {
|
||||
GCMARKVALUE(slots[i].value)
|
||||
GCMARKVALUE(slots[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3212,7 +3225,7 @@ deleteClassProperty:
|
||||
{
|
||||
GCMARKOBJECT(parent)
|
||||
for (DynamicPropertyIterator i = dynamicProperties.begin(), end = dynamicProperties.end(); (i != end); i++) {
|
||||
GCMARKVALUE(i->second)
|
||||
GCMARKVALUE(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3226,7 +3239,7 @@ deleteClassProperty:
|
||||
// gc-mark all contained JS2Objects and visit contained structures to do likewise
|
||||
void MethodClosure::markChildren()
|
||||
{
|
||||
GCMARKVALUE(thisObject)
|
||||
GCMARKVALUE(thisObject);
|
||||
GCMARKOBJECT(method->fInst)
|
||||
}
|
||||
|
||||
@ -3263,7 +3276,7 @@ deleteClassProperty:
|
||||
Frame::markChildren();
|
||||
GCMARKOBJECT(internalNamespace)
|
||||
for (DynamicPropertyIterator i = dynamicProperties.begin(), end = dynamicProperties.end(); (i != end); i++) {
|
||||
GCMARKVALUE(i->second)
|
||||
GCMARKVALUE(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3283,7 +3296,7 @@ deleteClassProperty:
|
||||
void ParameterFrame::markChildren()
|
||||
{
|
||||
Frame::markChildren();
|
||||
GCMARKVALUE(thisObject)
|
||||
GCMARKVALUE(thisObject);
|
||||
}
|
||||
|
||||
|
||||
@ -3438,6 +3451,25 @@ deleteClassProperty:
|
||||
p->owner->returnToPond(p);
|
||||
}
|
||||
|
||||
void JS2Object::markJS2Value(js2val v)
|
||||
{
|
||||
if (JS2VAL_IS_OBJECT(v)) {
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(v);
|
||||
GCMARKOBJECT(obj);
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_DOUBLE(v))
|
||||
JS2Object::mark(JS2VAL_TO_DOUBLE(v));
|
||||
else
|
||||
if (JS2VAL_IS_LONG(v))
|
||||
JS2Object::mark(JS2VAL_TO_LONG(v));
|
||||
else
|
||||
if (JS2VAL_IS_ULONG(v))
|
||||
JS2Object::mark(JS2VAL_TO_ULONG(v));
|
||||
else
|
||||
if (JS2VAL_IS_FLOAT(v))
|
||||
JS2Object::mark(JS2VAL_TO_FLOAT(v));
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
*
|
||||
|
@ -127,8 +127,7 @@ public:
|
||||
};
|
||||
|
||||
#define GCMARKOBJECT(n) if ((n) && !(n)->isMarked()) { (n)->mark(); (n)->markChildren(); }
|
||||
#define GCMARKVALUE(v) if (JS2VAL_IS_OBJECT(v)) { JS2Object *_obj = JS2VAL_TO_OBJECT(v); GCMARKOBJECT(_obj) } \
|
||||
else { if (JS2VAL_IS_DOUBLE(v)) { JS2Object::mark(JS2VAL_TO_DOUBLE(v)); } }
|
||||
#define GCMARKVALUE(v) JS2Object::markJS2Value(v)
|
||||
|
||||
class JS2Object {
|
||||
// Every object is either undefined, null, a Boolean,
|
||||
@ -160,6 +159,7 @@ public:
|
||||
void mark() { ((PondScum *)this)[-1].mark(); }
|
||||
|
||||
static void mark(void *p) { ((PondScum *)p)[-1].mark(); }
|
||||
static void markJS2Value(js2val v);
|
||||
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,24 @@
|
||||
case eMinus:
|
||||
{
|
||||
a = pop();
|
||||
pushNumber(-toNumber(a));
|
||||
a = toGeneralNumber(a);
|
||||
if (JS2VAL_IS_LONG(a)) {
|
||||
int64 v = *JS2VAL_TO_LONG(a);
|
||||
if (JSLL_EQ(v, JSLL_MININT))
|
||||
meta->reportError(Exception::rangeError, "Arithmetic overflow", errorPos());
|
||||
JSLL_NEG(v, v);
|
||||
pushLong(v);
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_ULONG(a)) {
|
||||
uint64 v = *JS2VAL_TO_ULONG(a);
|
||||
if (JSLL_UCMP(v, >, JSLL_MAXINT))
|
||||
meta->reportError(Exception::rangeError, "Arithmetic overflow", errorPos());
|
||||
JSLL_NEG(v, v);
|
||||
pushLong(v);
|
||||
}
|
||||
else
|
||||
pushNumber(-toNumber(a));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -56,30 +73,71 @@
|
||||
{
|
||||
b = pop();
|
||||
a = pop();
|
||||
int32 count = toInteger(b) & 0x1F;
|
||||
pushNumber(toInteger(a) << count);
|
||||
a = toGeneralNumber(a);
|
||||
int32 count = toInteger(b);
|
||||
if (JS2VAL_IS_LONG(a)) {
|
||||
int64 r;
|
||||
JSLL_SHL(r, *JS2VAL_TO_LONG(a), count & 0x3F);
|
||||
pushLong(r);
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_ULONG(a)) {
|
||||
uint64 r;
|
||||
JSLL_SHL(r, *JS2VAL_TO_ULONG(a), count & 0x3F);
|
||||
pushULong(r);
|
||||
}
|
||||
else
|
||||
pushNumber(toInteger(a) << (count & 0x1F));
|
||||
}
|
||||
break;
|
||||
case eRightShift:
|
||||
{
|
||||
b = pop();
|
||||
a = pop();
|
||||
int32 count = toInteger(b) & 0x1F;
|
||||
pushNumber(toInteger(a) >> count);
|
||||
a = toGeneralNumber(a);
|
||||
int32 count = toInteger(b);
|
||||
if (JS2VAL_IS_LONG(a)) {
|
||||
int64 r;
|
||||
JSLL_SHR(r, *JS2VAL_TO_LONG(a), count & 0x3F);
|
||||
pushLong(r);
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_ULONG(a)) {
|
||||
uint64 r;
|
||||
JSLL_USHR(r, *JS2VAL_TO_ULONG(a), count & 0x3F);
|
||||
pushULong(r);
|
||||
}
|
||||
else
|
||||
pushNumber(toInteger(a) >> (count & 0x1F));
|
||||
}
|
||||
break;
|
||||
case eLogicalRightShift:
|
||||
{
|
||||
b = pop();
|
||||
a = pop();
|
||||
int32 count = toInteger(b) & 0x1F;
|
||||
pushNumber(toUInt32(toInteger(a)) >> count);
|
||||
a = toGeneralNumber(a);
|
||||
int32 count = toInteger(b);
|
||||
if (JS2VAL_IS_LONG(a)) {
|
||||
int64 r;
|
||||
JSLL_SHR(r, *JS2VAL_TO_LONG(a), count & 0x3F);
|
||||
pushLong(r);
|
||||
}
|
||||
else
|
||||
if (JS2VAL_IS_ULONG(a)) {
|
||||
uint64 r;
|
||||
JSLL_USHR(r, *JS2VAL_TO_ULONG(a), count & 0x3F);
|
||||
pushULong(r);
|
||||
}
|
||||
else
|
||||
pushNumber(toUInt32(toInteger(a)) >> (count & 0x1F));
|
||||
}
|
||||
break;
|
||||
case eBitwiseAnd:
|
||||
{
|
||||
b = pop();
|
||||
a = pop();
|
||||
b = toGeneralNumber(b);
|
||||
a = toGeneralNumber(a);
|
||||
pushNumber(toInteger(a) & toInteger(b));
|
||||
}
|
||||
break;
|
||||
|
@ -40,6 +40,20 @@
|
||||
}
|
||||
break;
|
||||
|
||||
case eUInt64:
|
||||
{
|
||||
pushULong(BytecodeContainer::getUInt64(pc));
|
||||
pc += sizeof(uint64);
|
||||
}
|
||||
break;
|
||||
|
||||
case eInt64:
|
||||
{
|
||||
pushLong(BytecodeContainer::getInt64(pc));
|
||||
pc += sizeof(int64);
|
||||
}
|
||||
break;
|
||||
|
||||
case eTrue:
|
||||
{
|
||||
push(JS2VAL_TRUE);
|
||||
|
@ -79,6 +79,8 @@
|
||||
#define INT_TO_JS2VAL(i) (((js2val)(i) << 1) | JS2VAL_INT)
|
||||
#define JS2VAL_TO_INT(v) ((int32)(v) >> 1)
|
||||
#define INT_FITS_IN_JS2VAL(i) ((uint32)((i)+JS2VAL_INT_MAX) <= 2*JS2VAL_INT_MAX)
|
||||
#define LONG_FITS_IN_JS2VAL(x) (JSLL_CMP((x), >, -JS2VAL_INT_MAX) && JSLL_CMP(JS2VAL_INT_MAX, >, (x)))
|
||||
#define ULONG_FITS_IN_JS2VAL(x) (JSLL_CMP(JS2VAL_INT_MAX, >, (x)))
|
||||
|
||||
#define JS2VAL_VOID INT_TO_JS2VAL(0 - JS2VAL_INT_POW2(30))
|
||||
#define JS2VAL_NULL OBJECT_TO_JS2VAL(0)
|
||||
|
@ -54,6 +54,10 @@
|
||||
** initializer
|
||||
***********************************************************************/
|
||||
|
||||
extern int64 JSLL_MaxInt();
|
||||
extern int64 JSLL_MinInt();
|
||||
extern int64 JSLL_Zero();
|
||||
|
||||
#define JSLL_MAXINT JSLL_MaxInt()
|
||||
#define JSLL_MININT JSLL_MinInt()
|
||||
#define JSLL_ZERO JSLL_Zero()
|
||||
@ -155,12 +159,26 @@
|
||||
** JSLL_D2L Convert float to 64 bit
|
||||
***********************************************************************/
|
||||
#define JSLL_L2I(i, l) ((i) = (int32)(l))
|
||||
#define JSLL_L2UI(ui, l) ((ui) = (uint32)(l))
|
||||
#define JSLL_UL2I(i, ul) ((i) = (int32)(ul))
|
||||
#define JSLL_L2UI(ui, l) ((ui) = (uint32)(l))
|
||||
#define JSLL_L2F(f, l) ((f) = (float64)(l))
|
||||
#define JSLL_L2D(d, l) ((d) = (float64)(l))
|
||||
#ifdef _WIN32
|
||||
#define JSLL_UL2D(d, ul) { \
|
||||
if (ul > JSLL_MAXINT) { \
|
||||
int64 _l2 = ul - JSLL_MAXINT; \
|
||||
JSLL_L2D(d, _l2); \
|
||||
(d) += JSLL_MININT; \
|
||||
} \
|
||||
else \
|
||||
(d) = (int64)ul; \
|
||||
}
|
||||
#else
|
||||
#define JSLL_UL2D(d, ul) ((d) = (float64)(ul))
|
||||
#endif
|
||||
|
||||
#define JSLL_I2L(l, i) ((l) = (int64)(i))
|
||||
#define JSLL_UI2L(l, ui) ((l) = (int64)(ui))
|
||||
#define JSLL_UI2L(l, ui) ((l) = (int64)(ui))
|
||||
#define JSLL_F2L(l, f) ((l) = (int64)(f))
|
||||
#define JSLL_D2L(l, d) ((l) = (int64)(d))
|
||||
|
||||
@ -383,6 +401,8 @@ extern void jsll_udivmod(uint64 *qp, uint64 *rp, uint64 a, uint64 b);
|
||||
(d) = -(d); \
|
||||
}
|
||||
|
||||
#define JSLL_UL2D(d, ul) ((d) = (double)ul.hi * 4.294967296e9 + ul.lo)
|
||||
|
||||
#define JSLL_I2L(l, i) { int32 _i = (i) >> 31; (l).lo = (i); (l).hi = _i; }
|
||||
#define JSLL_UI2L(l, ui) ((l).lo = (ui), (l).hi = 0)
|
||||
#define JSLL_F2L(l, f) { double _d = (double)f; JSLL_D2L(l, _d); }
|
||||
|
@ -56,9 +56,9 @@ static int64 ll_zero = JSLL_INIT( 0x00000000,0x00000000 );
|
||||
static int64 ll_maxint = JSLL_INIT( 0x7fffffff, 0xffffffff );
|
||||
static int64 ll_minint = JSLL_INIT( 0x80000000, 0x00000000 );
|
||||
|
||||
static int64 JSLL_Zero(void) { return ll_zero; }
|
||||
static int64 JSLL_MaxInt(void) { return ll_maxint; }
|
||||
static int64 JSLL_MinInt(void) { return ll_minint; }
|
||||
int64 JSLL_Zero(void) { return ll_zero; }
|
||||
int64 JSLL_MaxInt(void) { return ll_maxint; }
|
||||
int64 JSLL_MinInt(void) { return ll_minint; }
|
||||
//
|
||||
//
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user