📄 qscriptcontext_p.cpp
字号:
eng->objectConstructor->newObject(&nested_data->m_thisObject); nested_data->argc = argc; if (callee.m_object_value->m_scope.isValid()) activation_data->m_scope = callee.m_object_value->m_scope; else activation_data->m_scope = eng->m_globalObject; nested_data->tempStack = stackPtr; nested_data->args = &argp[1]; eng->newUndefined(&nested_data->m_result); QScriptObject *instance = nested_data->m_thisObject.m_object_value; // set [[prototype]] QScriptValueImpl dummy; QScript::Member proto; if (callee.resolve(eng->idTable()->id_prototype, &proto, &dummy, QScriptValue::ResolveLocal)) callee.get(proto, &instance->m_prototype); if (!instance->m_prototype.isObject()) instance->m_prototype = eng->objectConstructor->publicPrototype; function->execute(nested_data); --eng->m_callDepth; stackPtr = argp - 1; if (isReference) stackPtr -= 2; if (! nested_data->m_result.isValid()) eng->newUndefined(&nested_data->m_result); else if (! nested_data->m_result.isObject()) nested_data->m_result = nested_data->m_thisObject; if (nested_data->m_state == QScriptContext::ExceptionState) { eng->popContext(); Done(); } CHECK_TEMPSTACK(1); *++stackPtr = nested_data->m_result; eng->popContext(); ++iPtr; } Next(); I(FetchField): { QScriptValueImpl object = eng->toObject(stackPtr[-1]); if (! object.isValid()) { stackPtr -= 2; throwTypeError(QLatin1String("not an object")); HandleException(); } const QScriptValueImpl &m = stackPtr[0]; QScript::Ecma::Array::Instance *arrayInstance = 0; if (object.m_class == eng->arrayConstructor->classInfo()) arrayInstance = static_cast<QScript::Ecma::Array::Instance *> (object.m_object_value->m_data.data()); if (arrayInstance) { qint32 pos = toArrayIndex(m); if (pos != -1) { *--stackPtr = arrayInstance->value.at(pos); if (! stackPtr->isValid()) eng->newUndefined(&stackPtr[0]); ++iPtr; Next(); } } QScriptNameIdImpl *nameId = m.isString() ? m.m_string_value : 0; if (! nameId || ! nameId->unique) { QString str; if (m.isNumber()) qscript_uint_to_string(m.m_number_value, str); if (str.isEmpty()) str = eng->convertToNativeString(m); nameId = eng->nameId(str, /*persistent=*/false); } QScript::Member member; QScriptValueImpl base; if (object.resolve(nameId, &member, &base, QScriptValue::ResolvePrototype)) { base.get(member, --stackPtr); if (hasUncaughtException()) { stackPtr -= 1; HandleException(); } else if (member.isGetterOrSetter()) { // call the getter function QScriptValueImpl getter; if (member.isGetter()) { getter = *stackPtr; } else { if (!base.m_object_value->findGetter(&member)) { stackPtr -= 1; throwError(QLatin1String("No getter defined")); HandleException(); } base.get(member, &getter); } *stackPtr = getter.call(object); if (hasUncaughtException()) { stackPtr -= 1; Done(); } } } else { eng->newUndefined(--stackPtr); } ++iPtr; } Next(); I(FetchArguments): { CHECK_TEMPSTACK(1); if (!m_arguments.isValid()) { if (m_activation.objectValue() == m_thisObject.objectValue()) eng->newUndefined(&m_arguments); // ### arguments array parsed from command line else eng->newArguments(&m_arguments, m_activation, argc, m_callee); } *++stackPtr = m_arguments; ++iPtr; } Next(); I(DeclareLocal): { QScriptValueImpl &act = m_activation; QScriptNameIdImpl *memberName = iPtr->operand[0].m_string_value; bool readOnly = iPtr->operand[1].m_int_value != 0; QScript::Member member; QScriptValueImpl object; if (! act.resolve(memberName, &member, &object, QScriptValue::ResolveLocal)) { uint flags = QScriptValue::Undeletable; if (readOnly) flags |= QScript::Member::UninitializedConst | QScriptValue::ReadOnly; CREATE_MEMBER(act, memberName, &member, flags); act.put(member, undefined); } ++iPtr; } Next(); I(Assign): { if (! stackPtr[-1].isReference()) { stackPtr -= 2; throwSyntaxError(QLatin1String("invalid assignment lvalue")); HandleException(); } QScriptValue::ResolveFlags mode; mode = QScriptValue::ResolveFlags(stackPtr[-1].m_int_value) | QScriptValue::ResolvePrototype; QScriptValueImpl object = eng->toObject(stackPtr[-3]); if (! object.isValid()) { stackPtr -= 4; throwTypeError(QLatin1String("invalid assignment lvalue")); HandleException(); } const QScriptValueImpl &m = stackPtr[-2]; QScriptValueImpl &value = stackPtr[0]; qint32 pos = -1; QScript::Ecma::Array::Instance *arrayInstance = eng->arrayConstructor->get(object); if (arrayInstance) pos = toArrayIndex(m); stackPtr -= 3; if (pos != -1) arrayInstance->value.assign(pos, value); else { QScriptNameIdImpl *memberName; if (m.isString() && m.m_string_value->unique) memberName = m.m_string_value; else memberName = eng->nameId(eng->convertToNativeString(m), /*persistent=*/false); QScriptValueImpl base; QScript::Member member; const bool isMemberAssignment = (object.m_object_value != m_scopeChain.m_object_value); if (! object.resolve(memberName, &member, &base, mode)) { if (isMemberAssignment) base = object; else base = eng->m_globalObject; CREATE_MEMBER(base, memberName, &member, /*flags=*/0); } if (value.isString() && ! value.m_string_value->unique) eng->newNameId(&value, value.m_string_value->s); if (object.m_class == eng->m_class_with) object = object.prototype(); if (member.isGetterOrSetter()) { // find and call setter(value) QScriptValueImpl setter; if (!member.isSetter()) { if (!base.m_object_value->findSetter(&member)) { stackPtr -= 1; throwError(QLatin1String("no setter defined")); HandleException(); } } base.get(member, &setter); value = setter.call(object, QScriptValueImplList() << value); if (hasUncaughtException()) { stackPtr -= 1; Done(); } } else { if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { base = object; CREATE_MEMBER(base, memberName, &member, /*flags=*/0); } if (member.isWritable()) base.put(member, value); else if (member.isUninitializedConst()) { base.put(member, value); if (member.isObjectProperty()) { base.m_object_value->m_members[member.id()] .unsetFlags(QScript::Member::UninitializedConst); } } if (hasUncaughtException()) { stackPtr -= 1; HandleException(); } } } *stackPtr = value; ++iPtr; } Next(); I(BitAnd): { qint32 v1 = eng->convertToNativeInt32(stackPtr[-1]); qint32 v2 = eng->convertToNativeInt32(stackPtr[0]); eng->newNumber(--stackPtr, v1 & v2); ++iPtr; } Next(); I(BitOr): { qint32 v1 = eng->convertToNativeInt32(stackPtr[-1]); qint32 v2 = eng->convertToNativeInt32(stackPtr[0]); eng->newNumber(--stackPtr, v1 | v2); ++iPtr; } Next(); I(BitXor): { qint32 v1 = eng->convertToNativeInt32(stackPtr[-1]); qint32 v2 = eng->convertToNativeInt32(stackPtr[0]); eng->newNumber(--stackPtr, v1 ^ v2); ++iPtr; } Next(); I(BitNot): { qint32 v1 = eng->convertToNativeInt32(stackPtr[0]); eng->newNumber(stackPtr, ~v1); ++iPtr; } Next(); I(Not): { bool v1 = eng->convertToNativeBoolean(stackPtr[0]); eng->newBoolean(stackPtr, !v1); ++iPtr; } Next(); I(LeftShift): { qint32 v1 = eng->convertToNativeInt32(stackPtr[-1]); qint32 v2 = eng->convertToNativeInt32(stackPtr[0]) & 0x1f; eng->newNumber(--stackPtr, v1 << v2); ++iPtr; } Next(); I(Mod): { qsreal v1 = eng->convertToNativeDouble(stackPtr[-1]); qsreal v2 = eng->convertToNativeDouble(stackPtr[0]); eng->newNumber(--stackPtr, ::fmod(v1, v2)); ++iPtr; } Next(); I(RightShift): { qint32 v1 = eng->convertToNativeInt32(stackPtr[-1]); quint32 v2 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(stackPtr[0])) & 0x1f; eng->newNumber(--stackPtr, v1 >> v2); ++iPtr; } Next(); I(URightShift): { quint32 v1 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(stackPtr[-1])); qint32 v2 = eng->convertToNativeInt32(stackPtr[0]) & 0x1f; eng->newNumber(--stackPtr, v1 >> v2); ++iPtr; } Next(); I(InstanceOf): { QScriptValueImpl object = stackPtr[-1]; QScriptValueImpl ctor = stackPtr[0]; bool result = false; if (!ctor.isObject()) { stackPtr -= 2; throwTypeError(QLatin1String("invalid 'instanceof' operand")); HandleException(); } // ### fixme, this is not according to spec // only Function implements [[hasInstance]] if (object.isObject()) { QScriptValueImpl prototype = ctor.property(eng->idTable()->id_prototype); if (!prototype.isObject()) { stackPtr -= 2; throwTypeError(QLatin1String("instanceof: 'prototype' property is not an object")); HandleException(); } result = object.instanceOf_helper(prototype); } eng->newBoolean(--stackPtr, result); ++iPtr; } Next(); I(In): { QScriptValueImpl object = stackPtr[0]; if (!object.isObject()) { stackPtr -= 2; throwTypeError(QLatin1String("invalid 'in' operand")); HandleException(); } QString propertyName = eng->convertToNativeString(stackPtr[-1]); bool result = object.property(propertyName, QScriptValue::ResolvePrototype).isValid(); // ### hasProperty() eng->newBoolean(--stackPtr, result); ++iPtr; } Next(); I(Add): { QScriptValueImpl lhs = eng->toPrimitive(stackPtr[-1], QScriptValueImpl::NoTypeHint); QScriptValueImpl rhs = eng->toPrimitive(stackPtr[0], QScriptValueImpl::NoTypeHint); if (lhs.isString() || rhs.isString()) { QString tmp = eng->convertToNativeString(lhs); tmp += eng->convertToNativeString(rhs); eng->newNameId(--stackPtr, tmp); } else { qsreal tmp = eng->convertToNativeDouble(lhs); tmp += eng->convertToNativeDouble(rhs); eng->newNumber(--stackPtr, tmp); } ++iPtr; } Next(); I(Div): { qsreal v1 = eng->convertToNativeDouble(stackPtr[-1]); qsreal v2 = eng->convertToNativeDouble(stackPtr[0]); eng->newNumber(--stackPtr, v1 / v2); ++iPtr; } Next(); I(Equal): { bool v = eq_cmp(stackPtr[-1], stackPtr[0]); eng->newBoolean(--stackPtr, v); ++iPtr; } Next(); I(GreatOrEqual): { bool v = le_cmp(stackPtr[0], stackPtr[-1]); eng->newBoolean(--stackPtr, v); ++iPtr; } Next(); I(GreatThan): { bool v = lt_cmp(stackPtr[0], stackPtr[-1]); eng->newBoolean(--stackPtr, v); ++iPtr; } Next(); I(LessOrEqual): { bool v = le_cmp(stackPtr[-1], stackPtr[0]); eng->newBoolean(--stackPtr, v); ++iPtr; } Next(); I(LessThan): { bool v = lt_cmp(stackPtr[-1], stackPtr[0]); eng->newBoolean(--stackPtr, v); ++iPtr; } Next(); I(NotEqual): { bool v = ! eq_cmp(stackPtr[-1], stackPtr[0]); eng->newBoolean(--stackPtr, v); ++iPtr; } Next(); I(Mul): {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -