diff --git a/CHANGELOG.md b/CHANGELOG.md index f55cc45a..5e8acce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for calling constructors functions with NewInstance on Function - Build v8 with i18n support - Access "this" from function callback +- value.SameValue(otherValue) function to compare values for sameness ### Changed - Removed error return value from Context.Isolate() which never fails diff --git a/function_template.go b/function_template.go index c3b2bc57..4d95fe16 100644 --- a/function_template.go +++ b/function_template.go @@ -83,7 +83,7 @@ func goFunctionCallback(ctxref int, cbref int, thisAndArgs *C.ValuePtr, argsCoun args: make([]*Value, argsCount), } - argv := (*[1 << 30]C.ValuePtr)(unsafe.Pointer(thisAndArgs))[1:argsCount + 1:argsCount + 1] + argv := (*[1 << 30]C.ValuePtr)(unsafe.Pointer(thisAndArgs))[1 : argsCount+1 : argsCount+1] for i, v := range argv { val := &Value{ptr: v, ctx: ctx} info.args[i] = val diff --git a/v8go.cc b/v8go.cc index 032d6266..f1f66eb0 100644 --- a/v8go.cc +++ b/v8go.cc @@ -708,6 +708,17 @@ ValuePtr ValueToObject(ValuePtr ptr) { return tracked_value(ctx, new_val); } +int ValueSameValue(ValuePtr ptr, ValuePtr otherPtr) { + m_value* val1 = static_cast(ptr); + m_value* val2 = static_cast(otherPtr); + + ISOLATE_SCOPE(val1->iso); + Local value1 = val1->ptr.Get(iso); + Local value2 = val2->ptr.Get(iso); + + return value1->SameValue(value2); +} + int ValueIsUndefined(ValuePtr ptr) { LOCAL_VALUE(ptr); return value->IsUndefined(); diff --git a/v8go.h b/v8go.h index 3f865e83..5b1fc221 100644 --- a/v8go.h +++ b/v8go.h @@ -105,6 +105,7 @@ const char* ValueToDetailString(ValuePtr ptr); uint32_t ValueToUint32(ValuePtr ptr); extern ValueBigInt ValueToBigInt(ValuePtr ptr); extern ValuePtr ValueToObject(ValuePtr ptr); +int ValueSameValue(ValuePtr ptr, ValuePtr otherPtr); int ValueIsUndefined(ValuePtr ptr); int ValueIsNull(ValuePtr ptr); int ValueIsNullOrUndefined(ValuePtr ptr); diff --git a/value.go b/value.go index efa81916..79d373f4 100644 --- a/value.go +++ b/value.go @@ -224,6 +224,12 @@ func (v *Value) Uint32() uint32 { return uint32(C.ValueToUint32(v.ptr)) } +// SameValue returns true if the other value is the same value. +// This is equivalent to `Object.is(v, other)` in JS. +func (v *Value) SameValue(other *Value) bool { + return C.ValueSameValue(v.ptr, other.ptr) != 0 +} + // IsUndefined returns true if this value is the undefined value. See ECMA-262 4.3.10. func (v *Value) IsUndefined() bool { return C.ValueIsUndefined(v.ptr) != 0 diff --git a/value_test.go b/value_test.go index dc350567..d9a6b368 100644 --- a/value_test.go +++ b/value_test.go @@ -443,6 +443,27 @@ func TestValueFunction(t *testing.T) { } +func TestValueSameValue(t *testing.T) { + t.Parallel() + iso, _ := v8go.NewIsolate() + defer iso.Dispose() + ctx, _ := v8go.NewContext(iso) + defer ctx.Close() + + objTempl := v8go.NewObjectTemplate(iso) + obj1, err := objTempl.NewInstance(ctx) + failIf(t, err) + obj2, err := objTempl.NewInstance(ctx) + failIf(t, err) + + if obj1.Value.SameValue(obj2.Value) != false { + t.Errorf("SameValue on two different values didn't return false") + } + if obj1.Value.SameValue(obj1.Value) != true { + t.Errorf("SameValue on two of the same value didn't return true") + } +} + func TestValueIsXXX(t *testing.T) { t.Parallel() iso, _ := v8go.NewIsolate()