JavascriptBoolean.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. namespace Js
  7. {
  8. Var JavascriptBoolean::OP_LdTrue(ScriptContext*scriptContext)
  9. {
  10. return scriptContext->GetLibrary()->GetTrue();
  11. }
  12. Var JavascriptBoolean::OP_LdFalse(ScriptContext* scriptContext)
  13. {
  14. return scriptContext->GetLibrary()->GetFalse();
  15. }
  16. Js::Var JavascriptBoolean::ToVar(BOOL fValue, ScriptContext* scriptContext)
  17. {
  18. return
  19. fValue ?
  20. scriptContext->GetLibrary()->GetTrue() :
  21. scriptContext->GetLibrary()->GetFalse();
  22. }
  23. Var JavascriptBoolean::NewInstance(RecyclableObject* function, CallInfo callInfo, ...)
  24. {
  25. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  26. ARGUMENTS(args, callInfo);
  27. ScriptContext* scriptContext = function->GetScriptContext();
  28. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  29. // SkipDefaultNewObject function flag should have prevented the default object from
  30. // being created, except when call true a host dispatch.
  31. Var newTarget = callInfo.Flags & CallFlags_NewTarget ? args.Values[args.Info.Count] : args[0];
  32. bool isCtorSuperCall = (callInfo.Flags & CallFlags_New) && newTarget != nullptr && !JavascriptOperators::IsUndefined(newTarget);
  33. Assert(isCtorSuperCall || !(callInfo.Flags & CallFlags_New) || args[0] == nullptr
  34. || JavascriptOperators::GetTypeId(args[0]) == TypeIds_HostDispatch);
  35. BOOL value;
  36. if (args.Info.Count > 1)
  37. {
  38. value = JavascriptConversion::ToBoolean(args[1], scriptContext) ? true : false;
  39. }
  40. else
  41. {
  42. value = false;
  43. }
  44. if (callInfo.Flags & CallFlags_New)
  45. {
  46. RecyclableObject* pNew = scriptContext->GetLibrary()->CreateBooleanObject(value);
  47. return isCtorSuperCall ?
  48. JavascriptOperators::OrdinaryCreateFromConstructor(RecyclableObject::FromVar(newTarget), pNew, nullptr, scriptContext) :
  49. pNew;
  50. }
  51. return scriptContext->GetLibrary()->CreateBoolean(value);
  52. }
  53. // Boolean.prototype.valueOf as described in ES6 spec (draft 24) 19.3.3.3
  54. Var JavascriptBoolean::EntryValueOf(RecyclableObject* function, CallInfo callInfo, ...)
  55. {
  56. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  57. ARGUMENTS(args, callInfo);
  58. ScriptContext* scriptContext = function->GetScriptContext();
  59. Assert(!(callInfo.Flags & CallFlags_New));
  60. if(JavascriptBoolean::Is(args[0]))
  61. {
  62. return args[0];
  63. }
  64. else if (JavascriptBooleanObject::Is(args[0]))
  65. {
  66. JavascriptBooleanObject* booleanObject = JavascriptBooleanObject::FromVar(args[0]);
  67. return scriptContext->GetLibrary()->CreateBoolean(booleanObject->GetValue());
  68. }
  69. else
  70. {
  71. return TryInvokeRemotelyOrThrow(EntryValueOf, scriptContext, args, JSERR_This_NeedBoolean, _u("Boolean.prototype.valueOf"));
  72. }
  73. }
  74. // Boolean.prototype.toString as described in ES6 spec (draft 24) 19.3.3.2
  75. Var JavascriptBoolean::EntryToString(RecyclableObject* function, CallInfo callInfo, ...)
  76. {
  77. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  78. ARGUMENTS(args, callInfo);
  79. AssertMsg(args.Info.Count, "Should always have implicit 'this'.");
  80. ScriptContext* scriptContext = function->GetScriptContext();
  81. Assert(!(callInfo.Flags & CallFlags_New));
  82. BOOL bval;
  83. Var aValue = args[0];
  84. if(JavascriptBoolean::Is(aValue))
  85. {
  86. bval = JavascriptBoolean::FromVar(aValue)->GetValue();
  87. }
  88. else if (JavascriptBooleanObject::Is(aValue))
  89. {
  90. JavascriptBooleanObject* booleanObject = JavascriptBooleanObject::FromVar(aValue);
  91. bval = booleanObject->GetValue();
  92. }
  93. else
  94. {
  95. return TryInvokeRemotelyOrThrow(EntryToString, scriptContext, args, JSERR_This_NeedBoolean, _u("Boolean.prototype.toString"));
  96. }
  97. return bval ? scriptContext->GetLibrary()->GetTrueDisplayString() : scriptContext->GetLibrary()->GetFalseDisplayString();
  98. }
  99. RecyclableObject * JavascriptBoolean::CloneToScriptContext(ScriptContext* requestContext)
  100. {
  101. if (this->GetValue())
  102. {
  103. return requestContext->GetLibrary()->GetTrue();
  104. }
  105. return requestContext->GetLibrary()->GetFalse();
  106. }
  107. Var JavascriptBoolean::TryInvokeRemotelyOrThrow(JavascriptMethod entryPoint, ScriptContext * scriptContext, Arguments & args, int32 errorCode, PCWSTR varName)
  108. {
  109. if (JavascriptOperators::GetTypeId(args[0]) == TypeIds_HostDispatch)
  110. {
  111. Var result;
  112. if (RecyclableObject::FromVar(args[0])->InvokeBuiltInOperationRemotely(entryPoint, args, &result))
  113. {
  114. return result;
  115. }
  116. }
  117. // Don't error if we disabled implicit calls
  118. if(scriptContext->GetThreadContext()->RecordImplicitException())
  119. {
  120. JavascriptError::ThrowTypeError(scriptContext, errorCode, varName);
  121. }
  122. else
  123. {
  124. return scriptContext->GetLibrary()->GetUndefined();
  125. }
  126. }
  127. BOOL JavascriptBoolean::Equals(Var other, BOOL* value, ScriptContext * requestContext)
  128. {
  129. return JavascriptBoolean::Equals(this, other, value, requestContext);
  130. }
  131. BOOL JavascriptBoolean::Equals(JavascriptBoolean* left, Var right, BOOL* value, ScriptContext * requestContext)
  132. {
  133. switch (JavascriptOperators::GetTypeId(right))
  134. {
  135. case TypeIds_Integer:
  136. *value = left->GetValue() ? TaggedInt::ToInt32(right) == 1 : TaggedInt::ToInt32(right) == 0;
  137. break;
  138. case TypeIds_Number:
  139. *value = left->GetValue() ? JavascriptNumber::GetValue(right) == 1.0 : JavascriptNumber::GetValue(right) == 0.0;
  140. break;
  141. case TypeIds_Int64Number:
  142. *value = left->GetValue() ? JavascriptInt64Number::FromVar(right)->GetValue() == 1 : JavascriptInt64Number::FromVar(right)->GetValue() == 0;
  143. break;
  144. case TypeIds_UInt64Number:
  145. *value = left->GetValue() ? JavascriptUInt64Number::FromVar(right)->GetValue() == 1 : JavascriptUInt64Number::FromVar(right)->GetValue() == 0;
  146. break;
  147. case TypeIds_Boolean:
  148. *value = left->GetValue() == JavascriptBoolean::FromVar(right)->GetValue();
  149. break;
  150. case TypeIds_String:
  151. *value = left->GetValue() ? JavascriptConversion::ToNumber(right, requestContext) == 1.0 : JavascriptConversion::ToNumber(right, requestContext) == 0.0;
  152. break;
  153. case TypeIds_Symbol:
  154. *value = FALSE;
  155. break;
  156. case TypeIds_VariantDate:
  157. // == on a variant always returns false. Putting this in a
  158. // switch in each .Equals to prevent a perf hit by adding an
  159. // if branch to JavascriptOperators::Equal_Full
  160. *value = FALSE;
  161. break;
  162. case TypeIds_Undefined:
  163. case TypeIds_Null:
  164. default:
  165. *value = JavascriptOperators::Equal_Full(left->GetValue() ? TaggedInt::ToVarUnchecked(1) : TaggedInt::ToVarUnchecked(0), right, requestContext);
  166. break;
  167. }
  168. return true;
  169. }
  170. BOOL JavascriptBoolean::GetDiagValueString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext)
  171. {
  172. if (this->GetValue())
  173. {
  174. JavascriptString* trueDisplayString = GetLibrary()->GetTrueDisplayString();
  175. stringBuilder->Append(trueDisplayString->GetString(), trueDisplayString->GetLength());
  176. }
  177. else
  178. {
  179. JavascriptString* falseDisplayString = GetLibrary()->GetFalseDisplayString();
  180. stringBuilder->Append(falseDisplayString->GetString(), falseDisplayString->GetLength());
  181. }
  182. return TRUE;
  183. }
  184. BOOL JavascriptBoolean::GetDiagTypeString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext)
  185. {
  186. stringBuilder->AppendCppLiteral(_u("Boolean"));
  187. return TRUE;
  188. }
  189. RecyclableObject* JavascriptBoolean::ToObject(ScriptContext * requestContext)
  190. {
  191. return requestContext->GetLibrary()->CreateBooleanObject(this->GetValue() ? true : false);
  192. }
  193. Var JavascriptBoolean::GetTypeOfString(ScriptContext * requestContext)
  194. {
  195. return requestContext->GetLibrary()->GetBooleanTypeDisplayString();
  196. }
  197. } // namespace Js