| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "RuntimeLibraryPch.h"
- #if defined(ENABLE_INTL_OBJECT) || defined(ENABLE_JS_BUILTINS)
- #include "errstr.h"
- #include "Library/EngineInterfaceObject.h"
- #include "Types/DeferredTypeHandler.h"
- #define IfFailThrowHr(op) \
- if (FAILED(hr=(op))) \
- { \
- JavascriptError::MapAndThrowError(scriptContext, hr); \
- } \
- #define IfFailAssertAndThrowHr(op) \
- if (FAILED(hr=(op))) \
- { \
- AssertMsg(false, "HRESULT was a failure."); \
- JavascriptError::MapAndThrowError(scriptContext, hr); \
- } \
- #define SetPropertyOn(obj, propID, value) \
- obj->SetProperty(propID, value, Js::PropertyOperationFlags::PropertyOperation_None, nullptr) \
- #define SetStringPropertyOn(obj, propID, propValue) \
- SetPropertyOn(obj, propID, Js::JavascriptString::NewCopySz(propValue, scriptContext)) \
- #define SetHSTRINGPropertyOn(obj, propID, hstringValue) \
- SetStringPropertyOn(obj, propID, wgl->WindowsGetStringRawBuffer(hstringValue, &length)) \
- #define SetPropertyLOn(obj, literalProperty, value) \
- obj->SetProperty(Js::JavascriptString::NewCopySz(literalProperty, scriptContext), value, Js::PropertyOperationFlags::PropertyOperation_None, nullptr) \
- #define SetStringPropertyLOn(obj, literalProperty, propValue) \
- SetPropertyLOn(obj, literalProperty, Js::JavascriptString::NewCopySz(propValue, scriptContext)) \
- #define SetHSTRINGPropertyLOn(obj, literalProperty, hstringValue) \
- SetStringPropertyLOn(obj, literalProperty, wgl->WindowsGetStringRawBuffer(hstringValue, &length)) \
- #define SetPropertyBuiltInOn(obj, builtInPropID, value) \
- SetPropertyOn(obj, Js::PropertyIds::builtInPropID, value) \
- #define SetStringPropertyBuiltInOn(obj, builtInPropID, propValue) \
- SetPropertyBuiltInOn(obj, builtInPropID, Js::JavascriptString::NewCopySz(propValue, scriptContext))
- #define SetHSTRINGPropertyBuiltInOn(obj, builtInPropID, hstringValue) \
- SetStringPropertyBuiltInOn(obj, builtInPropID, wgl->WindowsGetStringRawBuffer(hstringValue, &length)) \
- #define GetPropertyFrom(obj, propertyID) \
- Js::JavascriptOperators::GetProperty(obj, propertyID, &propertyValue, scriptContext) \
- #define GetPropertyLFrom(obj, propertyName) \
- GetPropertyFrom(obj, scriptContext->GetOrAddPropertyIdTracked(propertyName, wcslen(propertyName)))
- #define GetPropertyBuiltInFrom(obj, builtInPropID) \
- GetPropertyFrom(obj, Js::PropertyIds::builtInPropID) \
- #define GetTypedPropertyBuiltInFrom(obj, builtInPropID, Type) \
- (GetPropertyFrom(obj, Js::PropertyIds::builtInPropID) && VarIs<Type>(propertyValue)) \
- #define HasPropertyOn(obj, propID) \
- Js::JavascriptOperators::HasProperty(obj, propID) \
- #define HasPropertyBuiltInOn(obj, builtInPropID) \
- HasPropertyOn(obj, Js::PropertyIds::builtInPropID) \
- #define HasPropertyLOn(obj, propertyName) \
- HasPropertyOn(obj, scriptContext->GetOrAddPropertyIdTracked(propertyName, wcslen(propertyName)))
- namespace Js
- {
- EngineExtensionObjectBase* EngineInterfaceObject::GetEngineExtension(EngineInterfaceExtensionKind extensionKind) const
- {
- AnalysisAssert(extensionKind >= 0 && extensionKind <= MaxEngineInterfaceExtensionKind);
- if (extensionKind <= MaxEngineInterfaceExtensionKind)
- {
- Assert(engineExtensions[extensionKind] == nullptr || engineExtensions[extensionKind]->GetExtensionKind() == extensionKind);
- return engineExtensions[extensionKind];
- }
- return nullptr;
- }
- void EngineInterfaceObject::SetEngineExtension(EngineInterfaceExtensionKind extensionKind, EngineExtensionObjectBase* extensionObject)
- {
- AnalysisAssert(extensionKind >= 0 && extensionKind <= MaxEngineInterfaceExtensionKind);
- if (extensionKind <= MaxEngineInterfaceExtensionKind)
- {
- Assert(engineExtensions[extensionKind] == nullptr);
- engineExtensions[extensionKind] = extensionObject;
- // Init the extensionObject if this was already initialized
- if (this->IsInitialized())
- {
- extensionObject->Initialize();
- }
- }
- }
- // initialize EngineInterfaceObject::EntryInfo
- #define EngineInterfaceBuiltIn2(propId, nativeMethod) NoProfileFunctionInfo EngineInterfaceObject::EntryInfo::nativeMethod(FORCE_NO_WRITE_BARRIER_TAG(EngineInterfaceObject::Entry_##nativeMethod));
- #define BuiltInRaiseException(exceptionType, exceptionID) NoProfileFunctionInfo EngineInterfaceObject::EntryInfo::BuiltIn_raise##exceptionID(FORCE_NO_WRITE_BARRIER_TAG(EngineInterfaceObject::Entry_BuiltIn_raise##exceptionID));
- #include "EngineInterfaceObjectBuiltIns.h"
- EngineInterfaceObject * EngineInterfaceObject::New(Recycler * recycler, DynamicType * type)
- {
- EngineInterfaceObject* newObject = NewObject<EngineInterfaceObject>(recycler, type);
- for (uint i = 0; i <= MaxEngineInterfaceExtensionKind; i++)
- {
- newObject->engineExtensions[i] = nullptr;
- }
- return newObject;
- }
- void EngineInterfaceObject::Initialize()
- {
- Recycler* recycler = this->GetRecycler();
- ScriptContext* scriptContext = this->GetScriptContext();
- JavascriptLibrary* library = scriptContext->GetLibrary();
- // CommonNativeInterfaces is used as a prototype for the other native interface objects
- // to share the common APIs without requiring everyone to access EngineInterfaceObject.Common.
- this->commonNativeInterfaces = DynamicObject::New(recycler,
- DynamicType::New(scriptContext, TypeIds_Object, library->GetNull(), nullptr,
- DeferredTypeHandler<InitializeCommonNativeInterfaces>::GetDefaultInstance()));
- library->AddMember(this, Js::PropertyIds::Common, this->commonNativeInterfaces);
- for (uint i = 0; i <= MaxEngineInterfaceExtensionKind; i++)
- {
- if (engineExtensions[i] != nullptr)
- {
- engineExtensions[i]->Initialize();
- }
- }
- }
- #if ENABLE_TTD
- void EngineInterfaceObject::MarkVisitKindSpecificPtrs(TTD::SnapshotExtractor* extractor)
- {
- extractor->MarkVisitVar(this->commonNativeInterfaces);
- }
- void EngineInterfaceObject::ProcessCorePaths()
- {
- this->GetScriptContext()->TTDWellKnownInfo->EnqueueNewPathVarAsNeeded(this, this->commonNativeInterfaces, _u("!commonNativeInterfaces"));
- }
- TTD::NSSnapObjects::SnapObjectType EngineInterfaceObject::GetSnapTag_TTD() const
- {
- return TTD::NSSnapObjects::SnapObjectType::SnapWellKnownObject;
- }
- void EngineInterfaceObject::ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc)
- {
- TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<void*, TTD::NSSnapObjects::SnapObjectType::SnapWellKnownObject>(objData, nullptr);
- }
- #endif
- bool EngineInterfaceObject::InitializeCommonNativeInterfaces(DynamicObject* commonNativeInterfaces, DeferredTypeHandlerBase * typeHandler, DeferredInitializeMode mode)
- {
- // start with 1 for CallInstanceFunction
- int initSlotCapacity = 1;
- #define GlobalMathBuiltIn(mathMethod) initSlotCapacity++;
- #define GlobalBuiltIn(global, method) initSlotCapacity++;
- #define GlobalBuiltInConstructor(global) initSlotCapacity++;
- #define BuiltInRaiseException(exceptionType, exceptionID) initSlotCapacity++;
- #define EngineInterfaceBuiltIn2(propId, nativeMethod) initSlotCapacity++;
- #include "EngineInterfaceObjectBuiltIns.h"
- typeHandler->Convert(commonNativeInterfaces, mode, initSlotCapacity);
- JavascriptLibrary* library = commonNativeInterfaces->GetScriptContext()->GetLibrary();
- #define GlobalMathBuiltIn(mathMethod) library->AddFunctionToLibraryObject(commonNativeInterfaces, PropertyIds::builtInMath##mathMethod, &Math::EntryInfo::mathMethod, 1);
- #define GlobalBuiltIn(global, method) library->AddFunctionToLibraryObject(commonNativeInterfaces, PropertyIds::builtIn##global##Entry##method, &global::EntryInfo::method, 1);
- #define GlobalBuiltInConstructor(global) SetPropertyOn(commonNativeInterfaces, PropertyIds::##global##, library->Get##global##Constructor());
- #define BuiltInRaiseException(exceptionType, exceptionID) library->AddFunctionToLibraryObject(commonNativeInterfaces, PropertyIds::raise##exceptionID, &EngineInterfaceObject::EntryInfo::BuiltIn_raise##exceptionID, 1);
- #define EngineInterfaceBuiltIn2(propId, nativeMethod) library->AddFunctionToLibraryObject(commonNativeInterfaces, PropertyIds::propId, &EngineInterfaceObject::EntryInfo::nativeMethod, 1);
- #include "EngineInterfaceObjectBuiltIns.h"
- library->AddFunctionToLibraryObject(commonNativeInterfaces, PropertyIds::builtInCallInstanceFunction, &EngineInterfaceObject::EntryInfo::CallInstanceFunction, 1);
- commonNativeInterfaces->SetHasNoEnumerableProperties(true);
- return true;
- }
- Var EngineInterfaceObject::Entry_GetErrorMessage(RecyclableObject *function, CallInfo callInfo, ...)
- {
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo);
- if (callInfo.Count < 2)
- {
- return scriptContext->GetLibrary()->GetUndefined();
- }
- int hr = Js::JavascriptConversion::ToInt32(args[1], scriptContext);
- int resourceId;
- switch(hr)
- {
- case ASYNCERR_NoErrorInErrorState:
- resourceId = 5200;
- break;
- case ASYNCERR_InvalidStatusArg:
- resourceId = 5201;
- break;
- case ASYNCERR_InvalidSenderArg:
- resourceId = 5202;
- break;
- default:
- AssertMsg(false, "Invalid HRESULT passed to GetErrorMessage. This shouldn't come from Promise.js - who called us?");
- return scriptContext->GetLibrary()->GetUndefined();
- }
- const int strLength = 1024;
- OLECHAR errorString[strLength];
- if(FGetResourceString(resourceId, errorString, strLength))
- {
- return Js::JavascriptString::NewCopySz(errorString, scriptContext);
- }
- AssertMsg(false, "FGetResourceString returned false.");
- return scriptContext->GetLibrary()->GetUndefined();
- }
- Var EngineInterfaceObject::Entry_LogDebugMessage(RecyclableObject *function, CallInfo callInfo, ...)
- {
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo);
- #if DBG
- if (callInfo.Count < 2 || !VarIs<JavascriptString>(args.Values[1]))
- {
- return scriptContext->GetLibrary()->GetUndefined();
- }
- JavascriptString* message = VarTo<JavascriptString>(args.Values[1]);
- Output::Print(message->GetString());
- Output::Flush();
- #endif
- return scriptContext->GetLibrary()->GetUndefined();
- }
- /* static */
- ScriptFunction *EngineInterfaceObject::CreateLibraryCodeScriptFunction(ScriptFunction *scriptFunction, JavascriptString *displayName, bool isConstructor, bool isJsBuiltIn, bool isPublic)
- {
- if (scriptFunction->GetFunctionProxy()->IsPublicLibraryCode())
- {
- // this can happen when we re-initialize Intl for a different mode -- for instance, if we have the following JS:
- // print((1).toLocaleString())
- // print(new Intl.NumberFormat().format(1))
- // Intl will first get initialized for Number, and then will get re-initialized for all of Intl. This will cause
- // Number.prototype.toLocaleString to be registered twice, which breaks some of our assertions below.
- return scriptFunction;
- }
- ScriptContext *scriptContext = scriptFunction->GetScriptContext();
- if (!isConstructor)
- {
- // set the ErrorOnNew attribute to disallow construction. JsBuiltIn/Intl functions are usually regular ScriptFunctions
- // (not lambdas or class methods), so they are usually constructable by default.
- FunctionInfo *info = scriptFunction->GetFunctionInfo();
- AssertMsg((info->GetAttributes() & FunctionInfo::Attributes::ErrorOnNew) == 0, "Why are we trying to disable construction of a function that already isn't constructable?");
- info->SetAttributes((FunctionInfo::Attributes) (info->GetAttributes() | FunctionInfo::Attributes::ErrorOnNew));
- // Assert that the type handler is deferred to ensure that we aren't overwriting previous modifications.
- // Script functions start with deferred type handlers, which undefer as soon as any property is modified.
- // Since the function that is passed in should be an inline function expression, its type should still be deferred by the time it gets here.
- AssertOrFailFast(scriptFunction->GetDynamicType()->GetTypeHandler()->IsDeferredTypeHandler());
- // give the function a type handler with name and length but without prototype
- DynamicTypeHandler::SetInstanceTypeHandler(scriptFunction, scriptContext->GetLibrary()->GetDeferredFunctionWithLengthTypeHandler());
- }
- else
- {
- AssertMsg((scriptFunction->GetFunctionInfo()->GetAttributes() & FunctionInfo::Attributes::ErrorOnNew) == 0, "Why is the function not constructable by default?");
- }
- if (isPublic)
- {
- // Use GetSz rather than GetString because we use wcsrchr below, which expects a null-terminated string
- // Callers can pass in a string like "get compare" or "Intl.Collator.prototype.resolvedOptions" -- only for the
- // latter do we extract a shortName.
- const char16 *methodNameBuf = displayName->GetSz();
- charcount_t methodNameLength = displayName->GetLength();
- const char16 *shortName = wcsrchr(methodNameBuf, _u('.'));
- charcount_t shortNameOffset = 0;
- if (shortName != nullptr)
- {
- shortName++;
- shortNameOffset = static_cast<charcount_t>(shortName - methodNameBuf);
- }
- scriptFunction->GetFunctionProxy()->EnsureDeserialized()->SetDisplayName(methodNameBuf, methodNameLength, shortNameOffset);
- // handle the name property AFTER handling isConstructor, because this can initialize the function's deferred type
- Var existingName = nullptr;
- if (JavascriptOperators::GetOwnProperty(scriptFunction, PropertyIds::name, &existingName, scriptContext, nullptr))
- {
- JavascriptString *existingNameString = VarTo<JavascriptString>(existingName);
- if (existingNameString->GetLength() == 0)
- {
- // Only overwrite the name of the function object if it was anonymous coming in
- // If the input function was named, it is likely intentional
- existingName = nullptr;
- }
- }
- if (existingName == nullptr || JavascriptOperators::IsUndefined(existingName))
- {
- // It is convenient to set the name here rather than in script, since it is often duplicated.
- JavascriptString *funcName = displayName;
- if (shortName)
- {
- funcName = JavascriptString::NewCopyBuffer(shortName, methodNameLength - shortNameOffset, scriptContext);
- }
- scriptFunction->SetPropertyWithAttributes(PropertyIds::name, funcName, PropertyConfigurable, nullptr);
- }
- scriptFunction->GetFunctionProxy()->SetIsPublicLibraryCode();
- }
- if (isJsBuiltIn)
- {
- scriptFunction->GetFunctionProxy()->SetIsJsBuiltInCode();
- // This makes it so that the given scriptFunction can't reference/close over any outside variables,
- // which is desirable for JsBuiltIns (though currently not for Intl)
- scriptFunction->SetEnvironment(const_cast<FrameDisplay *>(&StrictNullFrameDisplay));
- // TODO(jahorto): investigate force-inlining Intl code
- scriptFunction->GetFunctionProxy()->EnsureDeserialized();
- AssertOrFailFast(scriptFunction->HasFunctionBody());
- scriptFunction->GetFunctionBody()->SetJsBuiltInForceInline();
- }
- return scriptFunction;
- }
- Var EngineInterfaceObject::Entry_TagPublicLibraryCode(RecyclableObject *function, CallInfo callInfo, ...)
- {
- #pragma warning(push)
- #pragma warning(disable: 4189) // 'scriptContext': local variable is initialized but not referenced
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo);
- #pragma warning(pop)
- AssertOrFailFast((args.Info.Count == 3 || args.Info.Count == 4) && VarIs<ScriptFunction>(args.Values[1]) && VarIs<JavascriptString>(args.Values[2]));
- ScriptFunction *func = UnsafeVarTo<ScriptFunction>(args[1]);
- JavascriptString *methodName = UnsafeVarTo<JavascriptString>(args[2]);
- bool isConstructor = true;
- if (args.Info.Count == 4)
- {
- AssertOrFailFast(VarIs<JavascriptBoolean>(args.Values[3]));
- isConstructor = UnsafeVarTo<JavascriptBoolean>(args.Values[3])->GetValue();
- }
- // isConstructor = true is the default (when no 3rd arg is provided)
- return CreateLibraryCodeScriptFunction(func, methodName, isConstructor, false /* isJsBuiltIn */, true /* isPublic */);
- }
- /*
- * First parameter is the object onto which prototype should be set; second is the value
- */
- Var EngineInterfaceObject::Entry_SetPrototype(RecyclableObject *function, CallInfo callInfo, ...)
- {
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo);
- if (callInfo.Count < 3 || !DynamicObject::IsBaseDynamicObject(args.Values[1]) || !VarIs<RecyclableObject>(args.Values[2]))
- {
- return scriptContext->GetLibrary()->GetUndefined();
- }
- DynamicObject* obj = VarTo<DynamicObject>(args.Values[1]);
- RecyclableObject* value = VarTo<RecyclableObject>(args.Values[2]);
- obj->SetPrototype(value);
- return obj;
- }
- /*
- * First parameter is the array object.
- */
- Var EngineInterfaceObject::Entry_GetArrayLength(RecyclableObject *function, CallInfo callInfo, ...)
- {
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo);
- if (callInfo.Count < 2)
- {
- return scriptContext->GetLibrary()->GetUndefined();
- }
- if (DynamicObject::IsAnyArray(args.Values[1]))
- {
- JavascriptArray* arr = JavascriptArray::FromAnyArray(args.Values[1]);
- return TaggedInt::ToVarUnchecked(arr->GetLength());
- }
- else
- {
- AssertMsg(false, "Object passed in with unknown type ID, verify Intl.js is correct.");
- return TaggedInt::ToVarUnchecked(0);
- }
- }
- /*
- * First parameter is the string on which to match.
- * Second parameter is the regex object
- */
- Var EngineInterfaceObject::Entry_RegexMatch(RecyclableObject *function, CallInfo callInfo, ...)
- {
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo);
- if (callInfo.Count < 2 || !VarIs<JavascriptString>(args.Values[1]) || !VarIs<JavascriptRegExp>(args.Values[2]))
- {
- return scriptContext->GetLibrary()->GetUndefined();
- }
- JavascriptString *stringToUse = VarTo<JavascriptString>(args.Values[1]);
- JavascriptRegExp *regexpToUse = VarTo<JavascriptRegExp>(args.Values[2]);
- return RegexHelper::RegexMatchNoHistory(scriptContext, regexpToUse, stringToUse, false);
- }
- /*
- * First parameter is the function, then its the this arg; so at least 2 are needed.
- */
- Var EngineInterfaceObject::Entry_CallInstanceFunction(RecyclableObject *function, CallInfo callInfo, ...)
- {
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo);
- if (callInfo.Count < 3 || !JavascriptConversion::IsCallable(args.Values[1]))
- {
- return scriptContext->GetLibrary()->GetUndefined();
- }
- // TODO: This is marked volatile due to MSVC codegen bug in x86_test_pogo builds. Remove when the bug is fixed
- RecyclableObject *volatile func = VarTo<RecyclableObject>(args.Values[1]);
- AssertOrFailFastMsg(func != scriptContext->GetLibrary()->GetUndefined(), "Trying to callInstanceFunction(undefined, ...)");
- //Shift the arguments by 2 so argument at index 2 becomes the 'this' argument at index 0
- for (uint i = 0; i < args.Info.Count - 2; ++i)
- {
- args.Values[i] = args.Values[i + 2];
- }
- args.Info.Count -= 2;
- BEGIN_SAFE_REENTRANT_CALL(scriptContext->GetThreadContext())
- {
- return JavascriptFunction::CallFunction<true>(func, func->GetEntryPoint(), args);
- }
- END_SAFE_REENTRANT_CALL
- }
- #define BuiltInRaiseException(exceptionType, exceptionID) \
- Var EngineInterfaceObject::Entry_BuiltIn_raise##exceptionID(RecyclableObject *function, CallInfo callInfo, ...) \
- { \
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo); \
- \
- JavascriptError::Throw##exceptionType(scriptContext, JSERR_##exceptionID); \
- }
- #define BuiltInRaiseException1(exceptionType, exceptionID) \
- Var EngineInterfaceObject::Entry_BuiltIn_raise##exceptionID(RecyclableObject *function, CallInfo callInfo, ...) \
- { \
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo); \
- \
- if(args.Info.Count < 2 || !VarIs<JavascriptString>(args.Values[1])) \
- { \
- Assert(false); \
- JavascriptError::Throw##exceptionType(scriptContext, JSERR_##exceptionID); \
- } \
- JavascriptError::Throw##exceptionType##Var(scriptContext, JSERR_##exceptionID, VarTo<JavascriptString>(args.Values[1])->GetSz()); \
- }
- #define BuiltInRaiseException2(exceptionType, exceptionID) \
- Var EngineInterfaceObject::Entry_BuiltIn_raise##exceptionID(RecyclableObject *function, CallInfo callInfo, ...) \
- { \
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo); \
- \
- if(args.Info.Count < 3 || !VarIs<JavascriptString>(args.Values[1]) || !VarIs<JavascriptString>(args.Values[2])) \
- { \
- Assert(false); \
- JavascriptError::Throw##exceptionType(scriptContext, JSERR_##exceptionID); \
- } \
- JavascriptError::Throw##exceptionType##Var(scriptContext, JSERR_##exceptionID, VarTo<JavascriptString>(args.Values[1])->GetSz(), VarTo<JavascriptString>(args.Values[2])->GetSz()); \
- }
- #define BuiltInRaiseException3(exceptionType, exceptionID) \
- Var EngineInterfaceObject::Entry_BuiltIn_raise##exceptionID##_3(RecyclableObject *function, CallInfo callInfo, ...) \
- { \
- EngineInterfaceObject_CommonFunctionProlog(function, callInfo); \
- \
- if(args.Info.Count < 4 || !VarIs<JavascriptString>(args.Values[1]) || !VarIs<JavascriptString>(args.Values[2]) || !VarIs<JavascriptString>(args.Values[3])) \
- { \
- Assert(false); \
- JavascriptError::Throw##exceptionType(scriptContext, JSERR_##exceptionID); \
- } \
- JavascriptError::Throw##exceptionType##Var(scriptContext, JSERR_##exceptionID, VarTo<JavascriptString>(args.Values[1])->GetSz(), VarTo<JavascriptString>(args.Values[2])->GetSz(), VarTo<JavascriptString>(args.Values[3])->GetSz()); \
- }
- #include "EngineInterfaceObjectBuiltIns.h"
- }
- #endif // ENABLE_INTL_OBJECT || ENABLE_JS_BUILTINS
|