Пример #1
0
int main(int argc, char **argv)
{
    // expecting a filename
    if (argc < 2) {
        fprintf(stderr, "You have to specify at least one filename\n");
        return -1;
    }
    
    bool ret = true;
    {
        JSLock lock;
        
        // create interpreter w/ global object
        Global* global = new Global();
        RefPtr<Interpreter> interp = new Interpreter(global);
        ExecState *exec = interp->globalExec();
        
        MyObject *myObject = (MyObject *)_NPN_CreateObject (NPP(0), myFunctionPtrs);
        
// FIXME
//        global->put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::CLanguage, (void *)myObject));
        
        for (int i = 1; i < argc; i++) {
            const char *code = readJavaScriptFromFile(argv[i]);
            
            if (code) {
                // run
                Completion comp(interp->evaluate("", 0, code));
                
                if (comp.complType() == Throw) {
                    JSValue *exVal = comp.value();
                    char *msg = exVal->toString(exec).ascii();
                    int lineno = -1;
                    if (exVal->type() == ObjectType) {
                        JSValue *lineVal = exVal->getObject()->get(exec, Identifier("line"));
                        if (lineVal->type() == NumberType)
                            lineno = int(lineVal->toNumber(exec));
                    }
                    if (lineno != -1)
                        fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
                    else
                        fprintf(stderr,"Exception: %s\n",msg);
                    ret = false;
                }
                else if (comp.complType() == ReturnValue) {
                    char *msg = comp.value()->toString(interp->globalExec()).ascii();
                    fprintf(stderr,"Return value: %s\n",msg);
                }
            }
        }
                
        _NPN_ReleaseObject ((NPObject *)myObject);
        
    } // end block, so that Interpreter and global get deleted
    
    return ret ? 0 : 3;
}
Пример #2
0
JSObject* BalRuntimeObjectImp::construct(ExecState* exec, const ArgList& args)
{
    // ECMA 15.2.2.1 (?)
    CallData callData;
    CallType callType = getCallData(callData);
    JSValue* val = call(exec, this, callType, callData, this, args);

    if (!val || val->type() == NullType || val->type() == UndefinedType)
        return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype()->prototype());
    else
        return val->toObject(exec);
}
Пример #3
0
bool UserObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
    if (!fJSUserObject)
        return false;

    CFStringRef cfPropName = IdentifierToCFString(propertyName);
    JSUserObject *jsResult = fJSUserObject->CopyProperty(cfPropName);
    ReleaseCFType(cfPropName);
    if (jsResult) {
        slot.setCustom(this, userObjectGetter);
        jsResult->Release();
        return true;
    } else {
        JSValue *kjsValue = toPrimitive(exec);
        if (kjsValue->type() != NullType && kjsValue->type() != UndefinedType) {
            JSObject *kjsObject = kjsValue->toObject(exec);
            if (kjsObject->getPropertySlot(exec, propertyName, slot))
                return true;
        }
    }
    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
Пример #4
0
void JSObject::defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc)
{
    JSValue *o = getDirect(propertyName);
    GetterSetterImp *gs;

    if (o && o->type() == GetterSetterType) {
        gs = static_cast<GetterSetterImp *>(o);
    } else {
        gs = new GetterSetterImp;
        putDirect(propertyName, gs, GetterSetter);
    }

    _prop.setHasGetterSetterProperties(true);
    gs->setSetter(setterFunc);
}
Пример #5
0
static ALWAYS_INLINE JSValue *tryGetAndCallProperty(ExecState *exec, const JSObject *object, const Identifier &propertyName) {
  JSValue *v = object->get(exec, propertyName);
  if (v->isObject()) {
    JSObject *o = static_cast<JSObject*>(v);
    if (o->implementsCall()) { // spec says "not primitive type" but ...
      JSObject *thisObj = const_cast<JSObject*>(object);
      JSValue *def = o->call(exec, thisObj, List::empty());
      JSType defType = def->type();
      ASSERT(defType != GetterSetterType);
      if (defType != ObjectType)
        return def;
    }
  }
  return NULL;
}
Пример #6
0
// ECMA 15.2.2
JSObject* ObjectObjectImp::construct(ExecState* exec, const List& args)
{
  JSValue* arg = args[0];
  switch (arg->type()) {
  case StringType:
  case BooleanType:
  case NumberType:
  case ObjectType:
      return arg->toObject(exec);
  case NullType:
  case UndefinedType:
      return new JSObject(exec->lexicalInterpreter()->builtinObjectPrototype());
  default:
      //### ASSERT_NOT_REACHED();
      return 0;
  }
}
Пример #7
0
//#ifndef NDEBUG
void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
{
    UString vString;
    if (!o) {
        fprintf(stderr, "KJS: %s: (null)", s);
    } else {
        JSValue *v = o;

        unsigned int arrayLength = 0;
        bool hadExcep = exec->hadException();

        UString name;
        switch (v->type()) {
        case UnspecifiedType:
            name = "Unspecified";
            break;
        case UndefinedType:
            name = "Undefined";
            break;
        case NullType:
            name = "Null";
            break;
        case BooleanType:
            name = "Boolean";
            break;
        case StringType:
            name = "String";
            break;
        case NumberType:
            name = "Number";
            break;
        case ObjectType: {
            JSObject *obj = static_cast<JSObject *>(v);
            name = obj->className();
            if (name.isNull()) {
                name = "(unknown class)";
            }

            if (obj->inherits(&ArrayInstance::info)) {
                arrayLength = obj->get(exec, exec->propertyNames().length)->toUInt32(exec);
            }
            vString = "[object " + name + "]"; // krazy:exclude=doublequote_chars
            break;
        }
        case GetterSetterType:
            name = "GetterSetter";
            break;
        }

        // Avoid calling toString on a huge array (e.g. 4 billion elements, in mozilla/js/js1_5/Array/array-001.js)
        if (arrayLength > 100) {
            vString = UString("[ Array with ") + UString::from(arrayLength) + " elements ]";
        } else if (v->type() != ObjectType) { // Don't want to call a user toString function!
            vString = v->toString(exec);
        }
        if (!hadExcep) {
            exec->clearException();
        }

        if (vString.size() > 350) {
            vString = vString.substr(0, 350) + "...";
        }

        // Can't use two UString::ascii() in the same fprintf call
        CString tempString(vString.cstring());

        fprintf(stderr, "KJS: %s: %s : %s (%p)",
                s, tempString.c_str(), name.ascii(), (void *)v);

        if (lineno >= 0) {
            fprintf(stderr, ", line %d\n", lineno);
        } else {
            fprintf(stderr, "\n");
        }
    }
}
Пример #8
0
JSValue *ObjectProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
{
    switch (id) {
        case ValueOf:
            return thisObj;
        case HasOwnProperty: {
            PropertySlot slot;
            return jsBoolean(thisObj->getOwnPropertySlot(exec, Identifier(args[0]->toString(exec)), slot));
        }
        case IsPrototypeOf: {
            if (!args[0]->isObject())
                return jsBoolean(false);
         
            JSValue *v = static_cast<JSObject *>(args[0])->prototype();

            while (true) {
                if (!v->isObject())
                    return jsBoolean(false);
                
                if (thisObj == static_cast<JSObject *>(v))
                    return jsBoolean(true);
                
                v = static_cast<JSObject *>(v)->prototype();
            }
        }
        case DefineGetter: 
        case DefineSetter: {
            if (!args[1]->isObject() ||
                !static_cast<JSObject *>(args[1])->implementsCall()) {
                if (id == DefineGetter)
                    return throwError(exec, SyntaxError, "invalid getter usage");
                else
                    return throwError(exec, SyntaxError, "invalid setter usage");
            }

            if (id == DefineGetter)
                thisObj->defineGetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
            else
                thisObj->defineSetter(exec, Identifier(args[0]->toString(exec)), static_cast<JSObject *>(args[1]));
            return jsUndefined();
        }
        case LookupGetter:
        case LookupSetter: {
            Identifier propertyName = Identifier(args[0]->toString(exec));
            
            JSObject *obj = thisObj;
            while (true) {
                JSValue *v = obj->getDirect(propertyName);
                
                if (v) {
                    if (v->type() != GetterSetterType)
                        return jsUndefined();

                    JSObject *funcObj;
                        
                    if (id == LookupGetter)
                        funcObj = static_cast<GetterSetterImp *>(v)->getGetter();
                    else
                        funcObj = static_cast<GetterSetterImp *>(v)->getSetter();
                
                    if (!funcObj)
                        return jsUndefined();
                    else
                        return funcObj;
                }
                
                if (!obj->prototype() || !obj->prototype()->isObject())
                    return jsUndefined();
                
                obj = static_cast<JSObject *>(obj->prototype());
            }
        }
        case PropertyIsEnumerable:
            return jsBoolean(thisObj->propertyIsEnumerable(exec, Identifier(args[0]->toString(exec))));
        case ToLocaleString:
            return jsString(thisObj->toString(exec));
        case ToString:
        default:
            return jsString("[object " + thisObj->className() + "]");
    }
}