Search code examples
v8

Where in the V8 source does the automatic cast for BinaryOperation occour?


I stumbled again in the good old '12' + 2 = '122'

I wanted to deeply understand what happens here, so my first thesis was that

Maybe Javascript casts the right operand to the type of the first one and then operates, like so: '12' + String(2) = '122' all good...

But no, because 12 + '2' = '122' too; So the engine's magic is clearly favoring to concat over casting to number.

My second thesis was then

Maybe the engine enumerates all operands and looks for an "operator override", similar to C#? And then favor executing that over doing the self-magic thing?

My confusion got even weirder when I realized that also '5' * '8' = 40, it casts both operands to Number and does the operation. The only way I could possibly really understand that was to read the V8 code directly from GitHub

The farther I could track down was at v8/src/parsing/parser-base.h line 2865

// We have a "normal" binary operation.
x = factory()->NewBinaryOperation(op, x, y, pos);
if (op == Token::OR || op == Token::AND) {
  impl()->RecordBinaryOperationSourceRange(x, right_range);
}

From here I got lost, because I couldn't find where this factory() is coming from.

Long story short, where does the JavaScript "type Magic" come from in the V8 Engine Source code?


Solution

  • V8 developer here.

    There are several fast paths for various cases of addition and other operations in V8. If you want to study a canonical (slow, but complete) version, you can look for Object::Add in src/objects.cc.

    That said, the source of truth here is not any given engine's implementation, but the JavaScript specification. What the + operator is supposed to do is defined here: https://tc39.github.io/ecma262/#sec-addition-operator-plus. Any engine's implementation either does precisely that, or something that from the outside is indistinguishable from that -- otherwise it's a bug. It's not a coincidence that the implementation of Object::Add reads almost exactly like the spec ;-)