Esempio n. 1
0
    // Execute the ToString algorithm as described in ECMA-262 Section 9.8.
    // This is ToString(ToPrimitive(input argument, hint String))
    // ToPrimitive(input argument, hint String) calls [[DefaultValue]]
    // described in ECMA-262 8.6.2.6.  The [[DefaultValue]] algorithm
    // with hint String is inlined here.
    Stringp ScriptObject::toString()
    {
        AvmCore *core = this->core();
        Toplevel* toplevel = this->toplevel();

        Atom atomv_out[1];

        // call this.toString()
        // NOTE use callers versioned public to get correct toString
        Multiname tempname(core->findPublicNamespace(), core->ktoString);
        atomv_out[0] = atom();
        Atom result = toplevel->callproperty(atom(), &tempname, 0, atomv_out, vtable);

        // if result is primitive, return its ToString
        if (atomKind(result) != kObjectType)
            return core->string(result);

        // otherwise call this.valueOf()
        tempname.setName(core->kvalueOf);
        atomv_out[0] = atom();
        result = toplevel->callproperty(atom(), &tempname, 0, atomv_out, vtable);

        // if result is primitive, return it
        if (atomKind(result) != kObjectType)
            return core->string(result);

        // could not convert to primitive.
        toplevel->throwTypeError(kConvertToPrimitiveError, core->toErrorString(traits()));
        return NULL; // unreachable
    }
Esempio n. 2
0
    Stringp NumberClass::_convert(double n, int precision, int mode)
    {
        AvmCore* core = this->core();

        if (mode == MathUtils::DTOSTR_PRECISION)
        {
            if (precision < 1 || precision > 21) {
                toplevel()->throwRangeError(kInvalidPrecisionError, core->toErrorString(precision), core->toErrorString(1), core->toErrorString(21));
            }
        }
        else
        {
            if (precision < 0 || precision > 20) {
                toplevel()->throwRangeError(kInvalidPrecisionError, core->toErrorString(precision), core->toErrorString(0), core->toErrorString(20));
            }
        }

        return MathUtils::convertDoubleToString(core, n, mode, precision);
    }
Esempio n. 3
0
	ClassClosure* DomainObject::getClass(Stringp name)
	{
		AvmCore *core = this->core();

		if (name == NULL) {
			toplevel()->throwArgumentError(kNullArgumentError, core->toErrorString("name"));
		}

			
		// Search for a dot from the end.
        int dot = name->lastIndexOf(core->cachedChars[(int)'.']);
		
		// If there is a '.', this is a fully-qualified
		// class name in a package.  Must turn it into
		// a namespace-qualified multiname.
		Namespace* ns;
		Stringp className;
		if (dot >= 0) {
            Stringp uri = core->internString(name->substring(0, dot));
			ns = core->internNamespace(core->newNamespace(uri));
            className = core->internString(name->substring(dot+1, name->length()));
		} else {
			ns = core->publicNamespace;
			className = core->internString(name);
		}

		Multiname multiname(ns, className);

        // OOO: In the distribution, we search core->codeContext()->domainEnv rather than
        // our own domainEnv, which is surely a bug?
        ScriptObject *container = finddef(multiname, domainEnv);
		if (!container) {
			toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
		}
		Atom atom = toplevel()->getproperty(container->atom(),
											&multiname,
											container->vtable);

		if (!AvmCore::istype(atom, core->traits.class_itraits)) {
			toplevel()->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
		}
		return (ClassClosure*)AvmCore::atomToScriptObject(atom);
	}
Esempio n. 4
0
    void ProgramClass::_setExitListener(FunctionObject* f)
    {
        AvmCore *core = this->core();

        // Listeners MUST be functions or null
        if ( core->isNullOrUndefined(f->atom()) )
        {
            f = 0;
        }
        else if (!AvmCore::istype(f->atom(), core->traits.function_itraits))
        {
            toplevel()->argumentErrorClass()->throwError( kInvalidArgumentError, core->toErrorString("Function"));
        }

        exit_callback = f;
    }
	Atom DomainObject::loadBytes(ByteArrayObject *b)
	{
		AvmCore* core = this->core();
		if (!b)
			toplevel()->throwTypeError(kNullArgumentError, core->toErrorString("bytes"));

		ShellCodeContext* codeContext = new (core->GetGC()) ShellCodeContext();
		codeContext->m_domainEnv = domainEnv;

		// parse new bytecode
		size_t len = b->get_length();
		ScriptBuffer code = core->newScriptBuffer(len);
		VMPI_memcpy(code.getBuffer(), &b->GetByteArray()[0], len);
		Toplevel *toplevel = domainToplevel;
		return core->handleActionBlock(code, 0,
								  domainEnv,
								  toplevel,
								  NULL, codeContext);
	}
Esempio n. 6
0
    Stringp NumberClass::_numberToString(double dVal, int radix)
    {
        AvmCore* core = this->core();

        if (radix == 10 || MathUtils::isInfinite(dVal) || MathUtils::isNaN(dVal))
            return core->doubleToString(dVal);

        if (radix < 2 || radix > 36)
            toplevel()->throwRangeError(kInvalidRadixError, core->toErrorString(radix));

        // convertDoubleToStringRadix will convert the integer part of dVal
        // to a string in the specified radix, and it will handle large numbers
        // beyond the range of int/uint.  It will not handle the fractional
        // part.  To properly handle that, MathUtils::convertDoubleToString
        // would have to handle any base.  That's a lot of extra code and complexity for
        // something the ES3 spec says is implementation dependent
        // (i.e. we're not required to do it)

        return MathUtils::convertDoubleToStringRadix(core, dVal, radix);
    }
	void TraceClass::setListener(ScriptObject* f)
	{
	#ifdef DEBUGGER
		AvmCore *core = this->core();
		if (core->debugger())
		{
			// Listeners MUST be functions or null
			if ( core->isNullOrUndefined(f->atom()) )
			{
				f = 0;
			}
			else if (!AvmCore::istype(f->atom(), core->traits.function_itraits)) 
			{
				toplevel()->argumentErrorClass()->throwError( kInvalidArgumentError, core->toErrorString("Function"));
				return;
			}
			
			//MethodClosure* mc = f->toplevel()->methodClosureClass->create(f->getCallMethodEnv(), f->atom());
			core->debugger()->trace_callback = f;
		}
	#endif /* DEBUGGER */
		(void)f;
	}