Var JavascriptSet::EntryForEach(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Set.prototype.forEach")); if (!JavascriptSet::Is(args[0])) { JavascriptError::ThrowTypeErrorVar(scriptContext, JSERR_NeedObjectOfType, _u("Set.prototype.forEach"), _u("Set")); } JavascriptSet* set = JavascriptSet::FromVar(args[0]); if (args.Info.Count < 2 || !JavascriptConversion::IsCallable(args[1])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedFunction, _u("Set.prototype.forEach")); } RecyclableObject* callBackFn = RecyclableObject::FromVar(args[1]); Var thisArg = (args.Info.Count > 2) ? args[2] : scriptContext->GetLibrary()->GetUndefined(); auto iterator = set->GetIterator(); while (iterator.Next()) { Var value = iterator.Current(); CALL_FUNCTION(callBackFn, CallInfo(CallFlags_Value, 4), thisArg, value, value, args[0]); } return scriptContext->GetLibrary()->GetUndefined(); }
Var JavascriptReflect::EntrySet(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); Var undefinedValue = scriptContext->GetLibrary()->GetUndefined(); AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Reflect.set")); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); if (args.Info.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Reflect.set")); } if (args.Info.Count < 2 || !JavascriptOperators::IsObject(args[1])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedObject, _u("Reflect.set")); } Var target = args[1]; Var propertyKey = args.Info.Count > 2 ? args[2] : undefinedValue; Var value = args.Info.Count > 3 ? args[3] : undefinedValue; Var receiver = args.Info.Count > 4 ? args[4] : target; target = JavascriptOperators::ToObject(target, scriptContext); BOOL result = JavascriptOperators::SetElementIHelper(receiver, RecyclableObject::FromVar(target), propertyKey, value, scriptContext, PropertyOperationFlags::PropertyOperation_None); return scriptContext->GetLibrary()->GetTrueOrFalse(result); }
Var JavascriptReflect::EntryHas(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); Var undefinedValue = scriptContext->GetLibrary()->GetUndefined(); AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Reflect.has")); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); if (args.Info.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Reflect.has")); } if (args.Info.Count < 2 || !JavascriptOperators::IsObject(args[1])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedObject, _u("Reflect.has")); } Var target = args[1]; Var propertyKey = args.Info.Count > 2 ? args[2] : undefinedValue; BOOL result = JavascriptOperators::OP_HasItem(target, propertyKey, scriptContext); return scriptContext->GetLibrary()->GetTrueOrFalse(result); }
Var SIMDUint16x8Lib::EntryReplaceLane(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); Assert(!(callInfo.Flags & CallFlags_New)); // first arg has to be of type Uint16x8, so cannot be missing. if (args.Info.Count >= 4 && JavascriptSIMDUint16x8::Is(args[1])) { // if value arg is missing, then it is undefined. Var laneVar = args.Info.Count >= 4 ? args[2] : scriptContext->GetLibrary()->GetUndefined(); Var argVal = args.Info.Count >= 4 ? args[3] : scriptContext->GetLibrary()->GetUndefined(); uint16 value = JavascriptConversion::ToInt16(argVal, scriptContext); SIMDValue result = SIMD128ReplaceLane<JavascriptSIMDUint16x8, 8, uint16>(args[1], laneVar, value, scriptContext); return JavascriptSIMDUint16x8::New(&result, scriptContext); } JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdUint16x8TypeMismatch, _u("ReplaceLane")); }
Var JavascriptSymbol::NewInstance(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); CHAKRATEL_LANGSTATS_INC_BUILTINCOUNT(SymbolCount); // SkipDefaultNewObject function flag should have prevented the default object from // being created, except when call true a host dispatch. Var newTarget = callInfo.Flags & CallFlags_NewTarget ? args.Values[args.Info.Count] : args[0]; bool isCtorSuperCall = (callInfo.Flags & CallFlags_New) && newTarget != nullptr && !JavascriptOperators::IsUndefined(newTarget); Assert(isCtorSuperCall || !(callInfo.Flags & CallFlags_New) || args[0] == nullptr || JavascriptOperators::GetTypeId(args[0]) == TypeIds_HostDispatch); if (callInfo.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Symbol")); } JavascriptString* description; if (args.Info.Count > 1 && !JavascriptOperators::IsUndefined(args[1])) { description = JavascriptConversion::ToString(args[1], scriptContext); } else { description = scriptContext->GetLibrary()->GetEmptyString(); } return scriptContext->GetLibrary()->CreateSymbol(description); }
Var WebAssemblyTable::EntryGet(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); Assert(!(callInfo.Flags & CallFlags_New)); if (args.Info.Count == 0 || !WebAssemblyTable::Is(args[0])) { JavascriptError::ThrowTypeError(scriptContext, WASMERR_NeedTableObject); } WebAssemblyTable * table = WebAssemblyTable::FromVar(args[0]); Var indexVar = scriptContext->GetLibrary()->GetUndefined(); if (args.Info.Count >= 2) { indexVar = args[1]; } uint32 index = WebAssembly::ToNonWrappingUint32(indexVar, scriptContext); if (index >= table->m_currentLength) { JavascriptError::ThrowRangeError(scriptContext, JSERR_ArgumentOutOfRange); } if (!table->m_values[index]) { return scriptContext->GetLibrary()->GetNull(); } return table->m_values[index]; }
// Boolean.prototype.toString as described in ES6 spec (draft 24) 19.3.3.2 Var JavascriptBoolean::EntryToString(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); AssertMsg(args.Info.Count, "Should always have implicit 'this'."); ScriptContext* scriptContext = function->GetScriptContext(); Assert(!(callInfo.Flags & CallFlags_New)); BOOL bval; Var aValue = args[0]; if(JavascriptBoolean::Is(aValue)) { bval = JavascriptBoolean::FromVar(aValue)->GetValue(); } else if (JavascriptBooleanObject::Is(aValue)) { JavascriptBooleanObject* booleanObject = JavascriptBooleanObject::FromVar(aValue); bval = booleanObject->GetValue(); } else { return TryInvokeRemotelyOrThrow(EntryToString, scriptContext, args, JSERR_This_NeedBoolean, _u("Boolean.prototype.toString")); } return bval ? scriptContext->GetLibrary()->GetTrueDisplayString() : scriptContext->GetLibrary()->GetFalseDisplayString(); }
Var SIMDBool8x16Lib::EntryReplaceLane(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); Assert(!(callInfo.Flags & CallFlags_New)); if (args.Info.Count >= 4 && JavascriptSIMDBool8x16::Is(args[1])) { // if value arg is missing, then it is undefined. Var laneVar = args.Info.Count >= 4 ? args[2] : scriptContext->GetLibrary()->GetUndefined(); Var argVal = args.Info.Count >= 4 ? args[3] : scriptContext->GetLibrary()->GetUndefined(); bool value = JavascriptConversion::ToBool(argVal, scriptContext); int8 intValue = (value) ? -1 : 0; SIMDValue result = SIMDUtils::SIMD128ReplaceLane<JavascriptSIMDBool8x16, 16, int8>(args[1], laneVar, intValue, scriptContext); return JavascriptSIMDBool8x16::New(&result, scriptContext); } JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdBool8x16TypeMismatch, _u("ReplaceLane")); }
Var JavascriptGeneratorFunction::EntryGeneratorFunctionImplementation(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(stackArgs, callInfo); Assert(!(callInfo.Flags & CallFlags_New)); ScriptContext* scriptContext = function->GetScriptContext(); JavascriptGeneratorFunction* generatorFunction = JavascriptGeneratorFunction::FromVar(function); // InterpreterStackFrame takes a pointer to the args, so copy them to the recycler heap // and use that buffer for this InterpreterStackFrame. Field(Var)* argsHeapCopy = RecyclerNewArray(scriptContext->GetRecycler(), Field(Var), stackArgs.Info.Count); CopyArray(argsHeapCopy, stackArgs.Info.Count, stackArgs.Values, stackArgs.Info.Count); Arguments heapArgs(callInfo, (Var*)argsHeapCopy); DynamicObject* prototype = scriptContext->GetLibrary()->CreateGeneratorConstructorPrototypeObject(); JavascriptGenerator* generator = scriptContext->GetLibrary()->CreateGenerator(heapArgs, generatorFunction->scriptFunction, prototype); // Set the prototype from constructor JavascriptOperators::OrdinaryCreateFromConstructor(function, generator, prototype, scriptContext); // Call a next on the generator to execute till the beginning of the body CALL_ENTRYPOINT(scriptContext->GetThreadContext(), generator->EntryNext, function, CallInfo(CallFlags_Value, 1), generator); return generator; }
Var JavascriptWeakMap::EntryGet(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); if (!JavascriptWeakMap::Is(args[0])) { JavascriptError::ThrowTypeErrorVar(scriptContext, JSERR_NeedObjectOfType, _u("WeakMap.prototype.get"), _u("WeakMap")); } JavascriptWeakMap* weakMap = JavascriptWeakMap::FromVar(args[0]); Var key = (args.Info.Count > 1) ? args[1] : scriptContext->GetLibrary()->GetUndefined(); if (JavascriptOperators::IsObject(key) && JavascriptOperators::GetTypeId(key) != TypeIds_HostDispatch) { DynamicObject* keyObj = DynamicObject::FromVar(key); Var value = nullptr; if (weakMap->Get(keyObj, &value)) { return value; } } return scriptContext->GetLibrary()->GetUndefined(); }
Var JavascriptWeakMap::EntrySet(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); if (!JavascriptWeakMap::Is(args[0])) { JavascriptError::ThrowTypeErrorVar(scriptContext, JSERR_NeedObjectOfType, _u("WeakMap.prototype.set"), _u("WeakMap")); } JavascriptWeakMap* weakMap = JavascriptWeakMap::FromVar(args[0]); Var key = (args.Info.Count > 1) ? args[1] : scriptContext->GetLibrary()->GetUndefined(); Var value = (args.Info.Count > 2) ? args[2] : scriptContext->GetLibrary()->GetUndefined(); if (!JavascriptOperators::IsObject(key) || JavascriptOperators::GetTypeId(key) == TypeIds_HostDispatch) { // HostDispatch can not expand so can't have internal property added to it. // TODO: Support HostDispatch as WeakMap key JavascriptError::ThrowTypeError(scriptContext, JSERR_WeakMapSetKeyNotAnObject, _u("WeakMap.prototype.set")); } DynamicObject* keyObj = DynamicObject::FromVar(key); weakMap->Set(keyObj, value); return weakMap; }
Var JavascriptWeakSet::EntryHas(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); if (!JavascriptWeakSet::Is(args[0])) { JavascriptError::ThrowTypeErrorVar(scriptContext, JSERR_NeedObjectOfType, _u("WeakSet.prototype.has"), _u("WeakSet")); } JavascriptWeakSet* weakSet = JavascriptWeakSet::FromVar(args[0]); Var key = (args.Info.Count > 1) ? args[1] : scriptContext->GetLibrary()->GetUndefined(); bool hasValue = false; if (JavascriptOperators::IsObject(key) && JavascriptOperators::GetTypeId(key) != TypeIds_HostDispatch) { DynamicObject* keyObj = DynamicObject::FromVar(key); hasValue = weakSet->Has(keyObj); } return scriptContext->GetLibrary()->CreateBoolean(hasValue); }
Var JavascriptSymbol::NewInstance(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); CHAKRATEL_LANGSTATS_INC_DATACOUNT(ES6_Symbol); // SkipDefaultNewObject function flag should have prevented the default object from // being created, except when call true a host dispatch. JavascriptOperators::GetAndAssertIsConstructorSuperCall(args); if (callInfo.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Symbol")); } JavascriptString* description; if (args.Info.Count > 1 && !JavascriptOperators::IsUndefined(args[1])) { description = JavascriptConversion::ToString(args[1], scriptContext); } else { description = scriptContext->GetLibrary()->GetEmptyString(); } return scriptContext->GetLibrary()->CreateSymbol(description); }
Var JavascriptMap::EntrySet(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); if (!JavascriptMap::Is(args[0])) { JavascriptError::ThrowTypeErrorVar(scriptContext, JSERR_NeedObjectOfType, _u("Map.prototype.set"), _u("Map")); } JavascriptMap* map = JavascriptMap::FromVar(args[0]); Var key = (args.Info.Count > 1) ? args[1] : scriptContext->GetLibrary()->GetUndefined(); Var value = (args.Info.Count > 2) ? args[2] : scriptContext->GetLibrary()->GetUndefined(); if (JavascriptNumber::Is(key) && JavascriptNumber::IsNegZero(JavascriptNumber::GetValue(key))) { // Normalize -0 to +0 key = JavascriptNumber::New(0.0, scriptContext); } map->Set(key, value); return map; }
Var JavascriptError::EntryToString(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); Assert(!(callInfo.Flags & CallFlags_New)); if (args[0] == 0 || !JavascriptOperators::IsObject(args[0])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NeedObject, _u("Error.prototype.toString")); } RecyclableObject * thisError = RecyclableObject::FromVar(args[0]); Var value = NULL; JavascriptString *outputStr, *message; // get error.name BOOL hasName = JavascriptOperators::GetProperty(thisError, PropertyIds::name, &value, scriptContext, NULL) && JavascriptOperators::GetTypeId(value) != TypeIds_Undefined; if (hasName) { outputStr = JavascriptConversion::ToString(value, scriptContext); } else { outputStr = scriptContext->GetLibrary()->CreateStringFromCppLiteral(_u("Error")); } // get error.message if (JavascriptOperators::GetProperty(thisError, PropertyIds::message, &value, scriptContext, NULL) && JavascriptOperators::GetTypeId(value) != TypeIds_Undefined) { message = JavascriptConversion::ToString(value, scriptContext); } else { message = scriptContext->GetLibrary()->GetEmptyString(); } charcount_t nameLen = outputStr->GetLength(); charcount_t msgLen = message->GetLength(); if (nameLen > 0 && msgLen > 0) { outputStr = JavascriptString::Concat(outputStr, scriptContext->GetLibrary()->CreateStringFromCppLiteral(_u(": "))); outputStr = JavascriptString::Concat(outputStr, message); } else if (msgLen > 0) { outputStr = message; } return outputStr; }
Var JavascriptStringIterator::EntryNext(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); JavascriptLibrary* library = scriptContext->GetLibrary(); Assert(!(callInfo.Flags & CallFlags_New)); Var thisObj = args[0]; if (!JavascriptStringIterator::Is(thisObj)) { JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NeedStringIterator, L"String Iterator.prototype.next"); } JavascriptStringIterator* iterator = JavascriptStringIterator::FromVar(thisObj); JavascriptString* string = iterator->m_string; if (string == nullptr) { return library->CreateIteratorResultObjectUndefinedTrue(); } charcount_t length = string->GetLength(); charcount_t index = iterator->m_nextIndex; if (index >= length) { // Nulling out the m_string field is important so that the iterator // does not keep the string alive after iteration is completed. iterator->m_string = nullptr; return library->CreateIteratorResultObjectUndefinedTrue(); } wchar_t chFirst = string->GetItem(index); Var result; if (index + 1 == string->GetLength() || !NumberUtilities::IsSurrogateLowerPart(chFirst) || !NumberUtilities::IsSurrogateUpperPart(string->GetItem(index + 1))) { result = scriptContext->GetLibrary()->GetCharStringCache().GetStringForChar(chFirst); iterator->m_nextIndex += 1; } else { result = JavascriptString::SubstringCore(string, index, 2, scriptContext); iterator->m_nextIndex += 2; } return library->CreateIteratorResultObjectValueFalse(result); }
Var JavascriptError::NewURIErrorInstance(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); JavascriptError* pError = scriptContext->GetLibrary()->CreateURIError(); Var newTarget = callInfo.Flags & CallFlags_NewTarget ? args.Values[args.Info.Count] : args[0]; Var message = args.Info.Count > 1 ? args[1] : scriptContext->GetLibrary()->GetUndefined(); return JavascriptError::NewInstance(function, pError, callInfo, newTarget, message); }
Var JavascriptError::NewErrorInstance(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); JavascriptError* pError = scriptContext->GetLibrary()->CreateError(); // Process the arguments for IE specific behaviors for numbers and description JavascriptString* descriptionString = nullptr; bool hasNumber = false; double number = 0; if (args.Info.Count >= 3) { hasNumber = true; number = JavascriptConversion::ToNumber(args[1], scriptContext); // Get rid of this arg. NewInstance only expects a message arg. args.Values++; args.Info.Count--; descriptionString = JavascriptConversion::ToString(args[1], scriptContext); } else if (args.Info.Count == 2) { if (!hasNumber) { descriptionString = JavascriptConversion::ToString(args[1], scriptContext); } } else { hasNumber = true; descriptionString = scriptContext->GetLibrary()->GetEmptyString(); } Assert(descriptionString != nullptr); if (hasNumber) { JavascriptOperators::InitProperty(pError, PropertyIds::number, JavascriptNumber::ToVarNoCheck(number, scriptContext)); pError->SetNotEnumerable(PropertyIds::number); } JavascriptOperators::SetProperty(pError, pError, PropertyIds::description, descriptionString, scriptContext); pError->SetNotEnumerable(PropertyIds::description); return JavascriptError::NewInstance(function, pError, callInfo, args); }
Var DataView::EntrySetFloat64(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); BOOL isLittleEndian = FALSE; Assert(!(callInfo.Flags & CallFlags_New)); if (args.Info.Count == 0 || !DataView::Is(args[0])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NeedDataView); } if (args.Info.Count < 3) { JavascriptError::ThrowTypeError(scriptContext, JSERR_DataView_NeedArgument, L"offset or value"); } DataView* dataView = DataView::FromVar(args[0]); uint32 offset = JavascriptConversion::ToUInt32(args[1], scriptContext); double value = JavascriptConversion::ToNumber(args[2], scriptContext); if (args.Info.Count > 3) { isLittleEndian = JavascriptConversion::ToBoolean(args[3], scriptContext); } dataView->SetValue<double>(offset, value, L"DataView.prototype.SetFloat64", isLittleEndian); return scriptContext->GetLibrary()->GetUndefined(); }
Var SIMDBool8x16Lib::EntryBool8x16(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); Assert(!(callInfo.Flags & CallFlags_New)); Var undefinedVar = scriptContext->GetLibrary()->GetUndefined(); bool b[16]; // values uint argCount = args.Info.Count; for (uint i = 0; i < argCount - 1 && i < 16; i++) { b[i] = JavascriptConversion::ToBool(args[i + 1], scriptContext); } for (uint i = argCount - 1; i < 16; i++) { b[i] = JavascriptConversion::ToBool(undefinedVar, scriptContext); } SIMDValue lanes = SIMDBool8x16Operation::OpBool8x16(b); return JavascriptSIMDBool8x16::New(&lanes, scriptContext); }
// Q: Are we allowed to call this as a constructor ? Var SIMDInt8x16Lib::EntryInt8x16(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); Assert(!(callInfo.Flags & CallFlags_New)); Var undefinedVar = scriptContext->GetLibrary()->GetUndefined(); int8 intSIMDX0 = JavascriptConversion::ToInt8(args.Info.Count >= 2 ? args[1] : undefinedVar, scriptContext); int8 intSIMDX1 = JavascriptConversion::ToInt8(args.Info.Count >= 3 ? args[2] : undefinedVar, scriptContext); int8 intSIMDX2 = JavascriptConversion::ToInt8(args.Info.Count >= 4 ? args[3] : undefinedVar, scriptContext); int8 intSIMDX3 = JavascriptConversion::ToInt8(args.Info.Count >= 5 ? args[4] : undefinedVar, scriptContext); int8 intSIMDX4 = JavascriptConversion::ToInt8(args.Info.Count >= 6 ? args[5] : undefinedVar, scriptContext); int8 intSIMDX5 = JavascriptConversion::ToInt8(args.Info.Count >= 7 ? args[6] : undefinedVar, scriptContext); int8 intSIMDX6 = JavascriptConversion::ToInt8(args.Info.Count >= 8 ? args[7] : undefinedVar, scriptContext); int8 intSIMDX7 = JavascriptConversion::ToInt8(args.Info.Count >= 9 ? args[8] : undefinedVar, scriptContext); int8 intSIMDX8 = JavascriptConversion::ToInt8(args.Info.Count >= 10 ? args[9] : undefinedVar, scriptContext); int8 intSIMDX9 = JavascriptConversion::ToInt8(args.Info.Count >= 11 ? args[10] : undefinedVar, scriptContext); int8 intSIMDX10 = JavascriptConversion::ToInt8(args.Info.Count >= 12 ? args[11] : undefinedVar, scriptContext); int8 intSIMDX11 = JavascriptConversion::ToInt8(args.Info.Count >= 13 ? args[12] : undefinedVar, scriptContext); int8 intSIMDX12 = JavascriptConversion::ToInt8(args.Info.Count >= 14 ? args[13] : undefinedVar, scriptContext); int8 intSIMDX13 = JavascriptConversion::ToInt8(args.Info.Count >= 15 ? args[14] : undefinedVar, scriptContext); int8 intSIMDX14 = JavascriptConversion::ToInt8(args.Info.Count >= 16 ? args[15] : undefinedVar, scriptContext); int8 intSIMDX15 = JavascriptConversion::ToInt8(args.Info.Count >= 17 ? args[16] : undefinedVar, scriptContext); SIMDValue lanes = SIMDInt8x16Operation::OpInt8x16(intSIMDX0, intSIMDX1, intSIMDX2, intSIMDX3 , intSIMDX4, intSIMDX5, intSIMDX6, intSIMDX7 , intSIMDX8, intSIMDX9, intSIMDX10, intSIMDX11 , intSIMDX12, intSIMDX13, intSIMDX14, intSIMDX15); return JavascriptSIMDInt8x16::New(&lanes, scriptContext); }
Var SIMDUint16x8Lib::EntryUint16x8(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); Assert(!(callInfo.Flags & CallFlags_New)); Var undefinedVar = scriptContext->GetLibrary()->GetUndefined(); uint16 uintSIMDX0 = JavascriptConversion::ToUInt16(args.Info.Count >= 2 ? args[1] : undefinedVar, scriptContext); uint16 uintSIMDX1 = JavascriptConversion::ToUInt16(args.Info.Count >= 3 ? args[2] : undefinedVar, scriptContext); uint16 uintSIMDX2 = JavascriptConversion::ToUInt16(args.Info.Count >= 4 ? args[3] : undefinedVar, scriptContext); uint16 uintSIMDX3 = JavascriptConversion::ToUInt16(args.Info.Count >= 5 ? args[4] : undefinedVar, scriptContext); uint16 uintSIMDX4 = JavascriptConversion::ToUInt16(args.Info.Count >= 6 ? args[5] : undefinedVar, scriptContext); uint16 uintSIMDX5 = JavascriptConversion::ToUInt16(args.Info.Count >= 7 ? args[6] : undefinedVar, scriptContext); uint16 uintSIMDX6 = JavascriptConversion::ToUInt16(args.Info.Count >= 8 ? args[7] : undefinedVar, scriptContext); uint16 uintSIMDX7 = JavascriptConversion::ToUInt16(args.Info.Count >= 9 ? args[8] : undefinedVar, scriptContext); SIMDValue lanes = SIMDUint16x8Operation::OpUint16x8(uintSIMDX0, uintSIMDX1, uintSIMDX2, uintSIMDX3 , uintSIMDX4, uintSIMDX5, uintSIMDX6, uintSIMDX7); return JavascriptSIMDUint16x8::New(&lanes, scriptContext); }
// Symbol.keyFor as described in ES 2015 Var JavascriptSymbol::EntryKeyFor(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); AssertMsg(args.Info.Count, "Should always have implicit 'this'."); ScriptContext* scriptContext = function->GetScriptContext(); JavascriptLibrary* library = scriptContext->GetLibrary(); Assert(!(callInfo.Flags & CallFlags_New)); if (args.Info.Count < 2 || !JavascriptSymbol::Is(args[1])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NeedSymbol, _u("Symbol.keyFor")); } JavascriptSymbol* sym = JavascriptSymbol::FromVar(args[1]); const char16* key = sym->GetValue()->GetBuffer(); // Search the global symbol registration map for a key equal to the description of the symbol passed into Symbol.keyFor. // Symbol.for creates a new symbol with description equal to the key and uses that key as a mapping to the new symbol. // There will only be one symbol in the map with that string key value. const Js::PropertyRecord* propertyRecord = scriptContext->GetThreadContext()->GetSymbolFromRegistrationMap(key); // If we found a PropertyRecord in the map, make sure it is the same symbol that was passed to Symbol.keyFor. // If the two are different, it means the symbol passed to keyFor has the same description as a symbol registered via // Symbol.for _but_ is not the symbol returned from Symbol.for. if (propertyRecord != nullptr && propertyRecord == sym->GetValue()) { return JavascriptString::NewCopyBuffer(key, sym->GetValue()->GetLength(), scriptContext); } return library->GetUndefined(); }
BOOL ForInObjectEnumerator::GetCurrentEnumerator() { Assert(object); ScriptContext* scriptContext = GetScriptContext(); if (VirtualTableInfo<DynamicObject>::HasVirtualTable(object)) { DynamicObject* dynamicObject = (DynamicObject*)object; if (!dynamicObject->GetTypeHandler()->EnsureObjectReady(dynamicObject)) { return false; } dynamicObject->GetDynamicType()->PrepareForTypeSnapshotEnumeration(); embeddedEnumerator.Initialize(dynamicObject, true); currentEnumerator = &embeddedEnumerator; return true; } if (!object->GetEnumerator(TRUE /*enumNonEnumerable*/, (Var *)¤tEnumerator, scriptContext, true /*preferSnapshotSemantics */, enumSymbols)) { currentEnumerator = scriptContext->GetLibrary()->GetNullEnumerator(); return false; } return true; }
Var JavascriptReflect::EntryApply(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); Var undefinedValue = scriptContext->GetLibrary()->GetUndefined(); AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Reflect.apply")); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); if (args.Info.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Reflect.apply")); } Var target = args.Info.Count > 1 ? args[1] : undefinedValue; if (!JavascriptConversion::IsCallable(target)) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedFunction, _u("Reflect.apply")); } Var thisArgument = args.Info.Count > 2 ? args[2] : undefinedValue; Var argArray = args.Info.Count > 3 ? args[3] : undefinedValue; return JavascriptFunction::ApplyHelper(RecyclableObject::FromVar(target), thisArgument, argArray, scriptContext); }
Var JavascriptReflect::EntrySetPrototypeOf(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Reflect.setPrototypeOf")); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); if (args.Info.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Reflect.setPrototypeOf")); } if (args.Info.Count < 2 || !JavascriptOperators::IsObject(args[1])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedObject, _u("Reflect.setPrototypeOf")); } Var target = args[1]; target = JavascriptOperators::ToObject(target, scriptContext); if (args.Info.Count < 3 || !JavascriptOperators::IsObjectOrNull(args[2])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NotObjectOrNull, _u("Object.setPrototypeOf")); } RecyclableObject* newPrototype = RecyclableObject::FromVar(args[2]); BOOL changeResult = JavascriptObject::ChangePrototype(RecyclableObject::FromVar(target), newPrototype, /*validate*/false, scriptContext); return scriptContext->GetLibrary()->GetTrueOrFalse(changeResult); }
Var SharedArrayBuffer::NewInstance(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); Var newTarget = callInfo.Flags & CallFlags_NewTarget ? args.Values[args.Info.Count] : args[0]; bool isCtorSuperCall = (callInfo.Flags & CallFlags_New) && newTarget != nullptr && !JavascriptOperators::IsUndefined(newTarget); Assert(isCtorSuperCall || !(callInfo.Flags & CallFlags_New) || args[0] == nullptr); if (!(callInfo.Flags & CallFlags_New) || (newTarget && JavascriptOperators::IsUndefinedObject(newTarget))) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ClassConstructorCannotBeCalledWithoutNew, _u("SharedArrayBuffer")); } uint32 byteLength = 0; if (args.Info.Count > 1) { byteLength = GetByteLengthFromVar(scriptContext, args[1]); } RecyclableObject* newArr = scriptContext->GetLibrary()->CreateSharedArrayBuffer(byteLength); return isCtorSuperCall ? JavascriptOperators::OrdinaryCreateFromConstructor(RecyclableObject::FromVar(newTarget), newArr, nullptr, scriptContext) : newArr; }
Var JavascriptReflect::EntryPreventExtensions(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Reflect.preventExtensions")); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); if (args.Info.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Reflect.preventExtensions")); } if (args.Info.Count < 2 || !JavascriptOperators::IsObject(args[1])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedObject, _u("Reflect.preventExtensions")); } Var target = args[1]; RecyclableObject* targetObj = RecyclableObject::FromVar(target); GlobalObject* globalObject = targetObj->GetLibrary()->GetGlobalObject(); if (globalObject != targetObj && globalObject && (globalObject->ToThis() == targetObj)) { globalObject->PreventExtensions(); } return scriptContext->GetLibrary()->GetTrueOrFalse(targetObj->PreventExtensions()); }
Var JavascriptSet::EntryAdd(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); if (!JavascriptSet::Is(args[0])) { JavascriptError::ThrowTypeErrorVar(scriptContext, JSERR_NeedObjectOfType, _u("Set.prototype.add"), _u("Set")); } JavascriptSet* set = JavascriptSet::FromVar(args[0]); Var value = (args.Info.Count > 1) ? args[1] : scriptContext->GetLibrary()->GetUndefined(); if (JavascriptNumber::Is(value) && JavascriptNumber::IsNegZero(JavascriptNumber::GetValue(value))) { // Normalize -0 to +0 value = JavascriptNumber::New(0.0, scriptContext); } set->Add(value); return set; }
Var JavascriptReflect::EntryGetOwnPropertyDescriptor(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault); ARGUMENTS(args, callInfo); ScriptContext* scriptContext = function->GetScriptContext(); Var undefinedValue = scriptContext->GetLibrary()->GetUndefined(); AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, _u("Reflect.getOwnPropertyDescriptor")); AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'"); if (args.Info.Flags & CallFlags_New) { JavascriptError::ThrowTypeError(scriptContext, JSERR_ErrorOnNew, _u("Reflect.getOwnPropertyDescriptor")); } if (args.Info.Count < 2 || !JavascriptOperators::IsObject(args[1])) { JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedObject, _u("Reflect.getOwnPropertyDescriptor")); } Var target = args[1]; Var propertyKey = args.Info.Count > 2 ? args[2] : undefinedValue; if (JavascriptOperators::GetTypeId(target) == TypeIds_HostDispatch) { Var result; if (RecyclableObject::FromVar(target)->InvokeBuiltInOperationRemotely(EntryGetOwnPropertyDescriptor, args, &result)) { return result; } } return JavascriptObject::GetOwnPropertyDescriptorHelper(RecyclableObject::FromVar(target), propertyKey, scriptContext); }