On Tue, Nov 17, 2015 at 10:08 AM, Louis Santillan <[email protected]>
wrote:

> On Mon, Nov 16, 2015 at 9:44 PM, Arthur O'Dwyer <[email protected]
> > wrote:
>
>> I'm going to start using the following function for debugging purposes,
>> but *man* it would be nice if V8 provided something like this out of the
>> box. This is just Too Much Typing.
>>
>> uint64_t GetTypeFlags(const v8::Local<v8::Value>& v)
>> {
>>     uint64_t result = 0;
>>     if (v->IsArgumentsObject()   ) result |= 0x0000000000000001;
>>     if (v->IsArrayBuffer()       ) result |= 0x0000000000000002;
>>     if (v->IsArrayBufferView()   ) result |= 0x0000000000000004;
>>     if (v->IsArray()             ) result |= 0x0000000000000008;
>>     if (v->IsBooleanObject()     ) result |= 0x0000000000000010;
>>     if (v->IsBoolean()           ) result |= 0x0000000000000020;
>>     if (v->IsDataView()          ) result |= 0x0000000000000040;
>>     if (v->IsDate()              ) result |= 0x0000000000000080;
>>     if (v->IsExternal()          ) result |= 0x0000000000000100;
>>     if (v->IsFalse()             ) result |= 0x0000000000000200;
>>     if (v->IsFloat32Array()      ) result |= 0x0000000000000400;
>>     if (v->IsFloat64Array()      ) result |= 0x0000000000000800;
>>     if (v->IsFunction()          ) result |= 0x0000000000001000;
>>     if (v->IsGeneratorFunction() ) result |= 0x0000000000002000;
>>     if (v->IsGeneratorObject()   ) result |= 0x0000000000004000;
>>     if (v->IsInt16Array()        ) result |= 0x0000000000008000;
>>     if (v->IsInt32Array()        ) result |= 0x0000000000010000;
>>     if (v->IsInt32()             ) result |= 0x0000000000020000;
>>     if (v->IsInt8Array()         ) result |= 0x0000000000040000;
>>     if (v->IsMapIterator()       ) result |= 0x0000000000080000;
>>     if (v->IsMap()               ) result |= 0x0000000000100000;
>>     if (v->IsName()              ) result |= 0x0000000000200000;
>>     if (v->IsNativeError()       ) result |= 0x0000000000400000;
>>     if (v->IsNull()              ) result |= 0x0000000000800000;
>>     if (v->IsNumberObject()      ) result |= 0x0000000001000000;
>>     if (v->IsNumber()            ) result |= 0x0000000002000000;
>>     if (v->IsObject()            ) result |= 0x0000000004000000;
>>     if (v->IsPromise()           ) result |= 0x0000000008000000;
>>     if (v->IsRegExp()            ) result |= 0x0000000010000000;
>>     if (v->IsSetIterator()       ) result |= 0x0000000020000000;
>>     if (v->IsSet()               ) result |= 0x0000000040000000;
>>     if (v->IsStringObject()      ) result |= 0x0000000080000000;
>>     if (v->IsString()            ) result |= 0x0000000100000000;
>>     if (v->IsSymbolObject()      ) result |= 0x0000000200000000;
>>     if (v->IsSymbol()            ) result |= 0x0000000400000000;
>>     if (v->IsTrue()              ) result |= 0x0000000800000000;
>>     if (v->IsTypedArray()        ) result |= 0x0000001000000000;
>>     if (v->IsUint16Array()       ) result |= 0x0000002000000000;
>>     if (v->IsUint32Array()       ) result |= 0x0000004000000000;
>>     if (v->IsUint32()            ) result |= 0x0000008000000000;
>>     if (v->IsUint8Array()        ) result |= 0x0000010000000000;
>>     if (v->IsUint8ClampedArray() ) result |= 0x0000020000000000;
>>     if (v->IsUndefined()         ) result |= 0x0000040000000000;
>>     if (v->IsWeakMap()           ) result |= 0x0000080000000000;
>>     if (v->IsWeakSet()           ) result |= 0x0000100000000000;
>>     return result;
>> }
>>
>>
> Somebody correct me if I'm wrong, but OR'ing can result in an object
> tripping multiple flags.  Like a `var s = new String( "yo!" );` would
> trigger an IsObject & IsStringObject, and `var x = 42;` would trigger
> IsNumber, IsInt32, IsUint32.  Is that your intent Arthur?
>

Yes, that's correct. (And I've verified that those specific examples are
correct.)


> Do you really want to do duck typing via bit masking?

I'm not sure what you mean (that is, I know what *I* mean by "duck typing"
and "bit masking", but not what you mean by putting those words in that
order).  The goal of the function above is to take a v8::Value and give
back as much information about its type as possible. This is extremely
useful for debugging — particularly in cases where the C++ code is full of
"if (v->IsFoo() || v->IsBar() && !v->IsBaz() || ...)", because from the
bitmask you can see exactly which tests would have returned true. So for
example, if I'm writing a function that is supposed to work on Strings, but
my arg->IsString() test is failing, I can use GetTypeFlags(v) on one of the
failing objects to quickly determine that *maybe* I should be testing
(arg->IsString() || arg->IsStringObject()) instead — or at least that I
should go read up on IsStringObject() and see whether it changes my
understanding of the function I'm trying to write.

Whereas, the function you wrote will turn new String("yo!") into (1<<9) due
to the early return; I doubt there's any possible way for your function to
return (1<<19), because I *assume* that all StringObjects are also Objects.
However, if I'm wrong about that, my GetTypeFlags function could be
instrumented to tell me so, sooner or later. :)

–Arthur

-- 
-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to