1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/builtins/builtins_boolean.h" 17#include "ecmascript/js_primitive_ref.h" 18 19namespace panda::ecmascript::builtins { 20// ecma 19.3.1.1 Boolean(value) 21JSTaggedValue BuiltinsBoolean::BooleanConstructor(EcmaRuntimeCallInfo *argv) 22{ 23 BUILTINS_ENTRY_DEBUG_LOG(); 24 ASSERT(argv); 25 JSThread *thread = argv->GetThread(); 26 BUILTINS_API_TRACE(thread, Boolean, Constructor); 27 [[maybe_unused]] EcmaHandleScope handleScope(thread); 28 // 1. Let b be ToBoolean(value). 29 bool boolValue = GetCallArg(argv, 0)->ToBoolean(); 30 // 2. If NewTarget is undefined, return b. 31 JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv); 32 if (newTarget->IsUndefined()) { 33 return GetTaggedBoolean(boolValue); 34 } 35 // 3. Let O be OrdinaryCreateFromConstructor(NewTarget, "%BooleanPrototype%", [[BooleanData]] ). 36 // 5. Set the value of O's [[BooleanData]] internal slot to b. 37 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 38 JSHandle<JSFunction> ctor = JSHandle<JSFunction>(GetConstructor(argv)); 39 JSHandle<JSObject> result = factory->NewJSObjectByConstructor(ctor, newTarget); 40 // 4. ReturnIfAbrupt(O). 41 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 42 JSTaggedValue objValue = boolValue ? JSTaggedValue::True() : JSTaggedValue::False(); 43 JSPrimitiveRef::Cast(*result)->SetValue(thread, objValue); 44 // 6. Return O. 45 return result.GetTaggedValue(); 46} 47 48// ecma 19.3.3 abstract operation thisBooleanValue(value) 49JSTaggedValue BuiltinsBoolean::ThisBooleanValue(JSThread *thread, JSTaggedValue value) 50{ 51 BUILTINS_API_TRACE(thread, Boolean, ThisBooleanValue); 52 // 1. If Type(value) is Boolean, return value 53 if (value.IsBoolean()) { 54 return value; 55 } 56 // 2. If Type(value) is Object and value has a [[BooleanData]] internal slot, then 57 if (value.IsJSPrimitiveRef()) { 58 JSTaggedValue primitive = JSPrimitiveRef::Cast(value.GetTaggedObject())->GetValue(); 59 // a. Assert: value's [[BooleanData]] internal slot is a Boolean value. 60 if (primitive.IsBoolean()) { 61 // b. Return the value of value's [[BooleanData]] internal slot. 62 return primitive; 63 } 64 } 65 [[maybe_unused]] EcmaHandleScope handleScope(thread); 66 // 3. Throw a TypeError exception. 67 THROW_TYPE_ERROR_AND_RETURN(thread, "the type can not convert to BooleanValue", JSTaggedValue::Exception()); 68} 69 70// ecma 19.3.3.2 Boolean.prototype.toString () 71JSTaggedValue BuiltinsBoolean::BooleanPrototypeToString(EcmaRuntimeCallInfo *argv) 72{ 73 ASSERT(argv); 74 JSThread *thread = argv->GetThread(); 75 BUILTINS_API_TRACE(thread, Boolean, BooleanPrototypeToString); 76 [[maybe_unused]] EcmaHandleScope handleScope(thread); 77 // 1. Let b be thisBooleanValue(this value). 78 JSTaggedValue thisValueToBoolean = BuiltinsBoolean::ThisBooleanValue(thread, GetThis(argv).GetTaggedValue()); 79 // 2. ReturnIfAbrupt(b) 80 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 81 82 // 3. If b is true, return "true"; else return "false". 83 return thisValueToBoolean.IsTrue() ? GetTaggedString(thread, "true") : GetTaggedString(thread, "false"); 84} 85 86// ecma 19.3.3.3 Boolean.prototype.valueOf () 87JSTaggedValue BuiltinsBoolean::BooleanPrototypeValueOf(EcmaRuntimeCallInfo *argv) 88{ 89 ASSERT(argv); 90 JSThread *thread = argv->GetThread(); 91 BUILTINS_API_TRACE(thread, Boolean, BooleanPrototypeValueOf); 92 // 1. Return thisBooleanValue(this value). 93 return BuiltinsBoolean::ThisBooleanValue(thread, GetThis(argv).GetTaggedValue()); 94} 95} // namespace panda::ecmascript::builtins 96