diff options
Diffstat (limited to 'deps/v8/src/builtins')
119 files changed, 3106 insertions, 1970 deletions
diff --git a/deps/v8/src/builtins/OWNERS b/deps/v8/src/builtins/OWNERS new file mode 100644 index 0000000000..450423f878 --- /dev/null +++ b/deps/v8/src/builtins/OWNERS @@ -0,0 +1,3 @@ +file://COMMON_OWNERS + +# COMPONENT: Blink>JavaScript>Runtime diff --git a/deps/v8/src/builtins/accessors.cc b/deps/v8/src/builtins/accessors.cc index 25d37d73b4..ea6308622d 100644 --- a/deps/v8/src/builtins/accessors.cc +++ b/deps/v8/src/builtins/accessors.cc @@ -287,7 +287,8 @@ void Accessors::StringLengthGetter( if (!value.IsString()) { // Not a string value. That means that we either got a String wrapper or // a Value with a String wrapper in its prototype chain. - value = JSValue::cast(*Utils::OpenHandle(*info.Holder())).value(); + value = + JSPrimitiveWrapper::cast(*Utils::OpenHandle(*info.Holder())).value(); } Object result = Smi::FromInt(String::cast(value).length()); info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); @@ -305,7 +306,7 @@ Handle<AccessorInfo> Accessors::MakeStringLengthInfo(Isolate* isolate) { static Handle<Object> GetFunctionPrototype(Isolate* isolate, Handle<JSFunction> function) { if (!function->has_prototype()) { - Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function); + Handle<JSObject> proto = isolate->factory()->NewFunctionPrototype(function); JSFunction::SetPrototype(function, proto); } return Handle<Object>(function->prototype(), isolate); diff --git a/deps/v8/src/builtins/arguments.tq b/deps/v8/src/builtins/arguments.tq index add66917c0..6df5f801a3 100644 --- a/deps/v8/src/builtins/arguments.tq +++ b/deps/v8/src/builtins/arguments.tq @@ -34,13 +34,13 @@ namespace arguments { @export macro GetArgumentsFrameAndCount(implicit context: Context)(f: JSFunction): ArgumentsInfo { - let frame: Frame = LoadParentFramePointer(); + const frame: Frame = LoadParentFramePointer(); assert(frame.function == f); const shared: SharedFunctionInfo = f.shared_function_info; const formalParameterCount: bint = Convert<bint>(Convert<int32>(shared.formal_parameter_count)); - let argumentCount: bint = formalParameterCount; + const argumentCount: bint = formalParameterCount; const adaptor: ArgumentsAdaptorFrame = Cast<ArgumentsAdaptorFrame>(frame.caller) diff --git a/deps/v8/src/builtins/arm/builtins-arm.cc b/deps/v8/src/builtins/arm/builtins-arm.cc index 54c16932fa..9b9956b0fb 100644 --- a/deps/v8/src/builtins/arm/builtins-arm.cc +++ b/deps/v8/src/builtins/arm/builtins-arm.cc @@ -1093,11 +1093,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // 8-bit fields next to each other, so we could just optimize by writing a // 16-bit. These static asserts guard our assumption is valid. STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == - BytecodeArray::kOSRNestingLevelOffset + kCharSize); + BytecodeArray::kOsrNestingLevelOffset + kCharSize); STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); __ mov(r9, Operand(0)); __ strh(r9, FieldMemOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kOSRNestingLevelOffset)); + BytecodeArray::kOsrNestingLevelOffset)); // Load the initial bytecode offset. __ mov(kInterpreterBytecodeOffsetRegister, @@ -1509,13 +1509,16 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, __ ldr(fp, MemOperand( sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); + // Load builtin index (stored as a Smi) and use it to get the builtin start + // address from the builtins table. UseScratchRegisterScope temps(masm); - Register scratch = temps.Acquire(); - __ Pop(scratch); + Register builtin = temps.Acquire(); + __ Pop(builtin); __ add(sp, sp, Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); __ Pop(lr); - __ add(pc, scratch, Operand(Code::kHeaderSize - kHeapObjectTag)); + __ LoadEntryFromBuiltinIndex(builtin); + __ bx(builtin); } } // namespace @@ -2577,7 +2580,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, __ tst(sp, Operand(frame_alignment_mask)); __ b(eq, &alignment_as_expected); // Don't use Check here, as it will call Runtime_Abort re-entering here. - __ stop("Unexpected alignment"); + __ stop(); __ bind(&alignment_as_expected); } } @@ -2606,7 +2609,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, __ CompareRoot(r3, RootIndex::kTheHoleValue); // Cannot use check here as it attempts to generate call into runtime. __ b(eq, &okay); - __ stop("Unexpected pending exception"); + __ stop(); __ bind(&okay); } @@ -2835,19 +2838,25 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, DCHECK(function_address == r1 || function_address == r2); - Label profiler_disabled; - Label end_profiler_check; + Label profiler_enabled, end_profiler_check; __ Move(r9, ExternalReference::is_profiling_address(isolate)); __ ldrb(r9, MemOperand(r9, 0)); __ cmp(r9, Operand(0)); - __ b(eq, &profiler_disabled); - - // Additional parameter is the address of the actual callback. - __ Move(r3, thunk_ref); - __ jmp(&end_profiler_check); - - __ bind(&profiler_disabled); - __ Move(r3, function_address); + __ b(ne, &profiler_enabled); + __ Move(r9, ExternalReference::address_of_runtime_stats_flag()); + __ ldr(r9, MemOperand(r9, 0)); + __ cmp(r9, Operand(0)); + __ b(ne, &profiler_enabled); + { + // Call the api function directly. + __ Move(r3, function_address); + __ b(&end_profiler_check); + } + __ bind(&profiler_enabled); + { + // Additional parameter is the address of the actual callback. + __ Move(r3, thunk_ref); + } __ bind(&end_profiler_check); // Allocate HandleScope in callee-save registers. diff --git a/deps/v8/src/builtins/arm64/builtins-arm64.cc b/deps/v8/src/builtins/arm64/builtins-arm64.cc index f81a1955ee..bcee8f0b5d 100644 --- a/deps/v8/src/builtins/arm64/builtins-arm64.cc +++ b/deps/v8/src/builtins/arm64/builtins-arm64.cc @@ -1201,10 +1201,10 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // 8-bit fields next to each other, so we could just optimize by writing a // 16-bit. These static asserts guard our assumption is valid. STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == - BytecodeArray::kOSRNestingLevelOffset + kCharSize); + BytecodeArray::kOsrNestingLevelOffset + kCharSize); STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); __ Strh(wzr, FieldMemOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kOSRNestingLevelOffset)); + BytecodeArray::kOsrNestingLevelOffset)); // Load the initial bytecode offset. __ Mov(kInterpreterBytecodeOffsetRegister, @@ -1683,18 +1683,20 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, if (java_script_builtin) __ SmiUntag(kJavaScriptCallArgCountRegister); - // Load builtin object. + // Load builtin index (stored as a Smi) and use it to get the builtin start + // address from the builtins table. UseScratchRegisterScope temps(masm); Register builtin = temps.AcquireX(); - __ Ldr(builtin, - MemOperand(fp, BuiltinContinuationFrameConstants::kBuiltinOffset)); + __ Ldr( + builtin, + MemOperand(fp, BuiltinContinuationFrameConstants::kBuiltinIndexOffset)); // Restore fp, lr. __ Mov(sp, fp); __ Pop(fp, lr); - // Call builtin. - __ JumpCodeObject(builtin); + __ LoadEntryFromBuiltinIndex(builtin); + __ Jump(builtin); } } // namespace @@ -3400,16 +3402,23 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, DCHECK(function_address.is(x1) || function_address.is(x2)); - Label profiler_disabled; - Label end_profiler_check; + Label profiler_enabled, end_profiler_check; __ Mov(x10, ExternalReference::is_profiling_address(isolate)); __ Ldrb(w10, MemOperand(x10)); - __ Cbz(w10, &profiler_disabled); - __ Mov(x3, thunk_ref); - __ B(&end_profiler_check); - - __ Bind(&profiler_disabled); - __ Mov(x3, function_address); + __ Cbnz(w10, &profiler_enabled); + __ Mov(x10, ExternalReference::address_of_runtime_stats_flag()); + __ Ldrsw(w10, MemOperand(x10)); + __ Cbnz(w10, &profiler_enabled); + { + // Call the api function directly. + __ Mov(x3, function_address); + __ B(&end_profiler_check); + } + __ Bind(&profiler_enabled); + { + // Additional parameter is the address of the actual callback. + __ Mov(x3, thunk_ref); + } __ Bind(&end_profiler_check); // Save the callee-save registers we are going to use. diff --git a/deps/v8/src/builtins/array-copywithin.tq b/deps/v8/src/builtins/array-copywithin.tq index bfc95a28bf..94d871e8f7 100644 --- a/deps/v8/src/builtins/array-copywithin.tq +++ b/deps/v8/src/builtins/array-copywithin.tq @@ -9,7 +9,7 @@ namespace array_copywithin { // https://tc39.github.io/ecma262/#sec-array.prototype.copyWithin transitioning javascript builtin ArrayPrototypeCopyWithin( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); diff --git a/deps/v8/src/builtins/array-every.tq b/deps/v8/src/builtins/array-every.tq index 245b07556c..3451cd769b 100644 --- a/deps/v8/src/builtins/array-every.tq +++ b/deps/v8/src/builtins/array-every.tq @@ -4,8 +4,9 @@ namespace array { transitioning javascript builtin - ArrayEveryLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, + ArrayEveryLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a @@ -25,9 +26,10 @@ namespace array { } transitioning javascript builtin - ArrayEveryLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, - length: Object, result: Object): Object { + ArrayEveryLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object, + result: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -51,9 +53,9 @@ namespace array { } transitioning builtin ArrayEveryLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, thisArg: Object, - array: Object, o: JSReceiver, initialK: Number, length: Number, - initialTo: Object): Object { + _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _array: Object, o: JSReceiver, initialK: Number, length: Number, + _initialTo: Object): Object { // 5. Let k be 0. // 6. Repeat, while k < len for (let k: Number = initialK; k < length; k++) { @@ -88,7 +90,7 @@ namespace array { labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast<Smi>(len) otherwise goto Bailout(k); - let fastO: FastJSArray = Cast<FastJSArray>(o) otherwise goto Bailout(k); + const fastO: FastJSArray = Cast<FastJSArray>(o) otherwise goto Bailout(k); let fastOW = NewFastJSArrayWitness(fastO); // Build a fast loop over the smi array. @@ -109,12 +111,10 @@ namespace array { // https://tc39.github.io/ecma262/#sec-array.prototype.every transitioning javascript builtin - ArrayEvery(implicit context: Context)(receiver: Object, ...arguments): + ArrayEvery(js-implicit context: Context, receiver: Object)(...arguments): Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.every'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -144,8 +144,5 @@ namespace array { label TypeError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.every'); - } } } diff --git a/deps/v8/src/builtins/array-filter.tq b/deps/v8/src/builtins/array-filter.tq index 4bf175a787..9acd0d04ee 100644 --- a/deps/v8/src/builtins/array-filter.tq +++ b/deps/v8/src/builtins/array-filter.tq @@ -4,9 +4,10 @@ namespace array_filter { transitioning javascript builtin - ArrayFilterLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, array: Object, - initialK: Object, length: Object, initialTo: Object): Object { + ArrayFilterLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, array: Object, initialK: Object, + length: Object, initialTo: Object): Object { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -27,9 +28,10 @@ namespace array_filter { } transitioning javascript builtin - ArrayFilterLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, array: Object, - initialK: Object, length: Object, valueK: Object, initialTo: Object, + ArrayFilterLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, array: Object, initialK: Object, + length: Object, valueK: Object, initialTo: Object, result: Object): Object { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a @@ -42,9 +44,9 @@ namespace array_filter { const numberLength = Cast<Number>(length) otherwise unreachable; // This custom lazy deopt point is right after the callback. filter() needs - // to pick up at the next step, which is setting the callback result in - // the output array. After incrementing k and to, we can glide into the loop - // continuation builtin. + // to pick up at the next step, which is setting the callback + // result in the output array. After incrementing k and to, we can glide + // into the loop continuation builtin. if (ToBoolean(result)) { FastCreateDataProperty(outputArray, numberTo, valueK); numberTo = numberTo + 1; @@ -58,7 +60,7 @@ namespace array_filter { } transitioning builtin ArrayFilterLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, array: JSReceiver, o: JSReceiver, initialK: Number, length: Number, initialTo: Number): Object { let to: Number = initialTo; @@ -145,12 +147,10 @@ namespace array_filter { // https://tc39.github.io/ecma262/#sec-array.prototype.filter transitioning javascript builtin - ArrayFilter(implicit context: Context)(receiver: Object, ...arguments): + ArrayFilter(js-implicit context: Context, receiver: Object)(...arguments): Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.filter'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -199,8 +199,5 @@ namespace array_filter { label TypeError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.filter'); - } } } diff --git a/deps/v8/src/builtins/array-find.tq b/deps/v8/src/builtins/array-find.tq index 28223e4c49..ef54dd4666 100644 --- a/deps/v8/src/builtins/array-find.tq +++ b/deps/v8/src/builtins/array-find.tq @@ -4,8 +4,9 @@ namespace array_find { transitioning javascript builtin - ArrayFindLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, + ArrayFindLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object): Object { // All continuation points in the optimized find implementation are // after the ToObject(O) call that ensures we are dealing with a @@ -24,9 +25,10 @@ namespace array_find { } transitioning javascript builtin - ArrayFindLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, - length: Object, result: Object): Object { + ArrayFindLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + _callback: Object, _thisArg: Object, _initialK: Object, _length: Object, + _result: Object): Object { // This deopt continuation point is never actually called, it just // exists to make stack traces correct from a ThrowTypeError if the // callback was found to be non-callable. @@ -37,15 +39,16 @@ namespace array_find { // happens right after the callback and it's returned value must be handled // before iteration continues. transitioning javascript builtin - ArrayFindLoopAfterCallbackLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, - length: Object, foundValue: Object, isFound: Object): Object { + ArrayFindLoopAfterCallbackLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object, + foundValue: Object, isFound: Object): Object { // All continuation points in the optimized find implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; const callbackfn = Cast<Callable>(callback) otherwise unreachable; - let numberK = Cast<Number>(initialK) otherwise unreachable; + const numberK = Cast<Number>(initialK) otherwise unreachable; const numberLength = Cast<Number>(length) otherwise unreachable; // This custom lazy deopt point is right after the callback. find() needs @@ -62,7 +65,7 @@ namespace array_find { } transitioning builtin ArrayFindLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, o: JSReceiver, initialK: Number, length: Number): Object { // 5. Let k be 0. // 6. Repeat, while k < len @@ -116,12 +119,10 @@ namespace array_find { // https://tc39.github.io/ecma262/#sec-array.prototype.find transitioning javascript builtin - ArrayPrototypeFind(implicit context: Context)(receiver: Object, ...arguments): - Object { + ArrayPrototypeFind(js-implicit context: Context, receiver: Object)( + ...arguments): Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.find'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -151,8 +152,5 @@ namespace array_find { label NotCallableError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.find'); - } } } diff --git a/deps/v8/src/builtins/array-findindex.tq b/deps/v8/src/builtins/array-findindex.tq index 00d8378dfa..5a8bb85fba 100644 --- a/deps/v8/src/builtins/array-findindex.tq +++ b/deps/v8/src/builtins/array-findindex.tq @@ -4,8 +4,9 @@ namespace array_findindex { transitioning javascript builtin - ArrayFindIndexLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, + ArrayFindIndexLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object): Object { // All continuation points in the optimized findIndex implementation are // after the ToObject(O) call that ensures we are dealing with a @@ -24,9 +25,10 @@ namespace array_findindex { } transitioning javascript builtin - ArrayFindIndexLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, - length: Object, result: Object): Object { + ArrayFindIndexLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + _callback: Object, _thisArg: Object, _initialK: Object, _length: Object, + _result: Object): Object { // This deopt continuation point is never actually called, it just // exists to make stack traces correct from a ThrowTypeError if the // callback was found to be non-callable. @@ -37,16 +39,16 @@ namespace array_findindex { // happens right after the callback and it's returned value must be handled // before iteration continues. transitioning javascript builtin - ArrayFindIndexLoopAfterCallbackLazyDeoptContinuation(implicit context: - Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, - length: Object, foundValue: Object, isFound: Object): Object { + ArrayFindIndexLoopAfterCallbackLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object, + foundValue: Object, isFound: Object): Object { // All continuation points in the optimized findIndex implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; const callbackfn = Cast<Callable>(callback) otherwise unreachable; - let numberK = Cast<Number>(initialK) otherwise unreachable; + const numberK = Cast<Number>(initialK) otherwise unreachable; const numberLength = Cast<Number>(length) otherwise unreachable; // This custom lazy deopt point is right after the callback. find() needs @@ -64,7 +66,7 @@ namespace array_findindex { transitioning builtin ArrayFindIndexLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, o: JSReceiver, initialK: Number, length: Number): Number { // 5. Let k be 0. // 6. Repeat, while k < len @@ -118,12 +120,10 @@ namespace array_findindex { // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex transitioning javascript builtin - ArrayPrototypeFindIndex(implicit context: - Context)(receiver: Object, ...arguments): Object { + ArrayPrototypeFindIndex(js-implicit context: Context, receiver: Object)( + ...arguments): Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.findIndex'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -154,8 +154,5 @@ namespace array_findindex { label NotCallableError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.findIndex'); - } } } diff --git a/deps/v8/src/builtins/array-foreach.tq b/deps/v8/src/builtins/array-foreach.tq index d362e95950..f52d944291 100644 --- a/deps/v8/src/builtins/array-foreach.tq +++ b/deps/v8/src/builtins/array-foreach.tq @@ -4,8 +4,9 @@ namespace array_foreach { transitioning javascript builtin - ArrayForEachLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, + ArrayForEachLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object): Object { // All continuation points in the optimized forEach implemntation are // after the ToObject(O) call that ensures we are dealing with a @@ -21,9 +22,10 @@ namespace array_foreach { } transitioning javascript builtin - ArrayForEachLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, - length: Object, result: Object): Object { + ArrayForEachLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object, + _result: Object): Object { // All continuation points in the optimized forEach implemntation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -38,9 +40,9 @@ namespace array_foreach { } transitioning builtin ArrayForEachLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, thisArg: Object, - array: Object, o: JSReceiver, initialK: Number, len: Number, - to: Object): Object { + _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _array: Object, o: JSReceiver, initialK: Number, len: Number, + _to: Object): Object { // variables {array} and {to} are ignored. // 5. Let k be 0. @@ -72,7 +74,7 @@ namespace array_foreach { labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast<Smi>(len) otherwise goto Bailout(k); - let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k); + const fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k); let fastOW = NewFastJSArrayWitness(fastO); // Build a fast loop over the smi array. @@ -90,11 +92,10 @@ namespace array_foreach { // https://tc39.github.io/ecma262/#sec-array.prototype.foreach transitioning javascript builtin - ArrayForEach(context: Context, receiver: Object, ...arguments): Object { + ArrayForEach(js-implicit context: Context, receiver: Object)(...arguments): + Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.forEach'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -127,8 +128,5 @@ namespace array_foreach { label TypeError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.forEach'); - } } } diff --git a/deps/v8/src/builtins/array-join.tq b/deps/v8/src/builtins/array-join.tq index 72e1a3661e..c04233b222 100644 --- a/deps/v8/src/builtins/array-join.tq +++ b/deps/v8/src/builtins/array-join.tq @@ -37,7 +37,7 @@ namespace array_join { const array: JSArray = UnsafeCast<JSArray>(receiver); const fixedArray: FixedArray = UnsafeCast<FixedArray>(array.elements); const element: Object = fixedArray.objects[UnsafeCast<Smi>(k)]; - return element == Hole ? kEmptyString : element; + return element == TheHole ? kEmptyString : element; } LoadJoinElement<array::FastDoubleElements>( @@ -56,7 +56,7 @@ namespace array_join { assert(!IsDetachedBuffer(typedArray.buffer)); return typed_array::LoadFixedTypedArrayElementAsTagged( typedArray.data_ptr, UnsafeCast<Smi>(k), - typed_array::KindForArrayType<T>(), SMI_PARAMETERS); + typed_array::KindForArrayType<T>()); } transitioning builtin ConvertToLocaleString( @@ -103,8 +103,8 @@ namespace array_join { } CannotUseSameArrayAccessor<JSTypedArray>(implicit context: Context)( - loadFn: LoadJoinElementFn, receiver: JSReceiver, initialMap: Map, - initialLen: Number): never + _loadFn: LoadJoinElementFn, receiver: JSReceiver, _initialMap: Map, + _initialLen: Number): never labels Cannot, Can { const typedArray: JSTypedArray = UnsafeCast<JSTypedArray>(receiver); if (IsDetachedBuffer(typedArray.buffer)) goto Cannot; @@ -246,7 +246,7 @@ namespace array_join { case (nofSeparators: Number): { return StringRepeat(context, sep, nofSeparators); } - case (obj: Object): { + case (Object): { unreachable; } } @@ -448,7 +448,7 @@ namespace array_join { const previouslyVisited: Object = stack.objects[i]; // Add `receiver` to the first open slot - if (previouslyVisited == Hole) { + if (previouslyVisited == TheHole) { stack.objects[i] = receiver; return True; } @@ -473,7 +473,7 @@ namespace array_join { try { const stack: FixedArray = LoadJoinStack() otherwise IfUninitialized; - if (stack.objects[0] == Hole) { + if (stack.objects[0] == TheHole) { stack.objects[0] = receiver; } else if (JoinStackPush(stack, receiver) == False) deferred { @@ -504,7 +504,7 @@ namespace array_join { SetJoinStack(newStack); } else { - stack.objects[i] = Hole; + stack.objects[i] = TheHole; } return Undefined; } @@ -521,7 +521,7 @@ namespace array_join { // Builtin call was not nested (receiver is the first entry) and // did not contain other nested arrays that expanded the stack. if (stack.objects[0] == receiver && len == kMinJoinStackSize) { - StoreFixedArrayElement(stack, 0, Hole, SKIP_WRITE_BARRIER); + StoreFixedArrayElement(stack, 0, TheHole, SKIP_WRITE_BARRIER); } else deferred { JoinStackPop(stack, receiver); @@ -535,7 +535,7 @@ namespace array_join { sepObj: Object, locales: Object, options: Object): Object { // 3. If separator is undefined, let sep be the single-element String ",". // 4. Else, let sep be ? ToString(separator). - let sep: String = + const sep: String = sepObj == Undefined ? ',' : ToString_Inline(context, sepObj); // If the receiver is not empty and not already being joined, continue with @@ -557,7 +557,8 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-array.prototype.join transitioning javascript builtin - ArrayPrototypeJoin(context: Context, receiver: Object, ...arguments): Object { + ArrayPrototypeJoin(js-implicit context: Context, receiver: Object)( + ...arguments): Object { const separator: Object = arguments[0]; // 1. Let O be ? ToObject(this value). @@ -566,8 +567,8 @@ namespace array_join { // 2. Let len be ? ToLength(? Get(O, "length")). const len: Number = GetLengthProperty(o); - // Only handle valid array lengths. Although the spec allows larger values, - // this matches historical V8 behavior. + // Only handle valid array lengths. Although the spec allows larger + // values, this matches historical V8 behavior. if (len > kMaxArrayIndex + 1) ThrowTypeError(kInvalidArrayLength); return CycleProtectedArrayJoin<JSArray>( @@ -576,7 +577,7 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-array.prototype.tolocalestring transitioning javascript builtin ArrayPrototypeToLocaleString( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { const locales: Object = arguments[0]; const options: Object = arguments[1]; @@ -586,8 +587,8 @@ namespace array_join { // 2. Let len be ? ToLength(? Get(O, "length")). const len: Number = GetLengthProperty(o); - // Only handle valid array lengths. Although the spec allows larger values, - // this matches historical V8 behavior. + // Only handle valid array lengths. Although the spec allows larger + // values, this matches historical V8 behavior. if (len > kMaxArrayIndex + 1) ThrowTypeError(kInvalidArrayLength); return CycleProtectedArrayJoin<JSArray>( @@ -596,7 +597,7 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-array.prototype.tostring transitioning javascript builtin ArrayPrototypeToString( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { // 1. Let array be ? ToObject(this value). const array: JSReceiver = ToObject_Inline(context, receiver); @@ -617,7 +618,7 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.join transitioning javascript builtin TypedArrayPrototypeJoin( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { const separator: Object = arguments[0]; // Spec: ValidateTypedArray is applied to the this value prior to evaluating @@ -632,7 +633,7 @@ namespace array_join { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tolocalestring transitioning javascript builtin TypedArrayPrototypeToLocaleString( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { const locales: Object = arguments[0]; const options: Object = arguments[1]; diff --git a/deps/v8/src/builtins/array-lastindexof.tq b/deps/v8/src/builtins/array-lastindexof.tq index d6213157dc..5ebc451e43 100644 --- a/deps/v8/src/builtins/array-lastindexof.tq +++ b/deps/v8/src/builtins/array-lastindexof.tq @@ -12,7 +12,7 @@ namespace array_lastindexof { labels IfHole { const elements: FixedArray = UnsafeCast<FixedArray>(elements); const element: Object = elements.objects[index]; - if (element == Hole) goto IfHole; + if (element == TheHole) goto IfHole; return element; } @@ -131,7 +131,7 @@ namespace array_lastindexof { // https://tc39.github.io/ecma262/#sec-array.prototype.lastIndexOf transitioning javascript builtin ArrayPrototypeLastIndexOf( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { // 1. Let O be ? ToObject(this value). const object: JSReceiver = ToObject_Inline(context, receiver); diff --git a/deps/v8/src/builtins/array-map.tq b/deps/v8/src/builtins/array-map.tq index 7546f1cd00..dda569c682 100644 --- a/deps/v8/src/builtins/array-map.tq +++ b/deps/v8/src/builtins/array-map.tq @@ -4,9 +4,10 @@ namespace array_map { transitioning javascript builtin - ArrayMapLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, array: Object, - initialK: Object, length: Object): Object { + ArrayMapLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, array: Object, initialK: Object, + length: Object): Object { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -26,9 +27,10 @@ namespace array_map { } transitioning javascript builtin - ArrayMapLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, array: Object, - initialK: Object, length: Object, result: Object): Object { + ArrayMapLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, array: Object, initialK: Object, + length: Object, result: Object): Object { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -55,7 +57,7 @@ namespace array_map { } transitioning builtin ArrayMapLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, array: JSReceiver, o: JSReceiver, initialK: Number, length: Number): Object { // 6. Let k be 0. @@ -94,7 +96,7 @@ namespace array_map { } CreateJSArray(implicit context: Context)(validLength: Smi): JSArray { - let length: Smi = this.fixedArray.length; + const length: Smi = this.fixedArray.length; assert(validLength <= length); let kind: ElementsKind = PACKED_SMI_ELEMENTS; if (!this.onlySmis) { @@ -114,7 +116,7 @@ namespace array_map { kind = FastHoleyElementsKind(kind); } - let map: Map = LoadJSArrayElementsMap(kind, LoadNativeContext(context)); + const map: Map = LoadJSArrayElementsMap(kind, LoadNativeContext(context)); let a: JSArray; if (IsDoubleElementsKind(kind)) { @@ -130,7 +132,7 @@ namespace array_map { elements.floats[i] = Convert<float64>(n); } case (h: HeapObject): { - assert(h == Hole); + assert(h == TheHole); } } } @@ -182,11 +184,11 @@ namespace array_map { } transitioning macro FastArrayMap(implicit context: Context)( - fastO: FastJSArray, len: Smi, callbackfn: Callable, + fastO: FastJSArrayForRead, len: Smi, callbackfn: Callable, thisArg: Object): JSArray labels Bailout(JSArray, Smi) { let k: Smi = 0; - let fastOW = NewFastJSArrayWitness(fastO); + let fastOW = NewFastJSArrayForReadWitness(fastO); let vector = NewVector(len); // Build a fast loop over the smi array. @@ -220,24 +222,12 @@ namespace array_map { return vector.CreateJSArray(len); } - // Bails out if the slow path needs to be taken. - // It's useful to structure it this way, because the consequences of - // using the slow path on species creation are interesting to the caller. - macro FastMapSpeciesCreate(implicit context: Context)( - receiver: JSReceiver, length: Number): JSArray labels Bailout { - if (IsArraySpeciesProtectorCellInvalid()) goto Bailout; - const o = Cast<FastJSArray>(receiver) otherwise Bailout; - const smiLength = Cast<Smi>(length) otherwise Bailout; - const newMap: Map = - LoadJSArrayElementsMap(PACKED_SMI_ELEMENTS, LoadNativeContext(context)); - return AllocateJSArray(PACKED_SMI_ELEMENTS, newMap, smiLength, smiLength); - } - // https://tc39.github.io/ecma262/#sec-array.prototype.map transitioning javascript builtin - ArrayMap(implicit context: Context)(receiver: Object, ...arguments): Object { + ArrayMap(js-implicit context: Context, receiver: Object)(...arguments): + Object { try { - if (IsNullOrUndefined(receiver)) goto NullOrUndefinedError; + RequireObjectCoercible(receiver, 'Array.prototype.map'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -258,7 +248,7 @@ namespace array_map { try { // 5. Let A be ? ArraySpeciesCreate(O, len). if (IsArraySpeciesProtectorCellInvalid()) goto SlowSpeciesCreate; - const o: FastJSArray = Cast<FastJSArray>(receiver) + const o: FastJSArrayForRead = Cast<FastJSArrayForRead>(receiver) otherwise SlowSpeciesCreate; const smiLength: Smi = Cast<Smi>(len) otherwise SlowSpeciesCreate; @@ -279,8 +269,5 @@ namespace array_map { label TypeError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.map'); - } } } diff --git a/deps/v8/src/builtins/array-of.tq b/deps/v8/src/builtins/array-of.tq index 76123207fd..7293318625 100644 --- a/deps/v8/src/builtins/array-of.tq +++ b/deps/v8/src/builtins/array-of.tq @@ -5,7 +5,8 @@ namespace array_of { // https://tc39.github.io/ecma262/#sec-array.of transitioning javascript builtin - ArrayOf(implicit context: Context)(receiver: Object, ...arguments): Object { + ArrayOf(js-implicit context: Context, receiver: Object)(...arguments): + Object { // 1. Let len be the actual number of arguments passed to this function. const len: Smi = Convert<Smi>(arguments.length); @@ -35,7 +36,7 @@ namespace array_of { // 7. Repeat, while k < len while (k < len) { // a. Let kValue be items[k]. - let kValue: Object = items[Convert<intptr>(k)]; + const kValue: Object = items[Convert<intptr>(k)]; // b. Let Pk be ! ToString(k). // c. Perform ? CreateDataPropertyOrThrow(A, Pk, kValue). diff --git a/deps/v8/src/builtins/array-reduce-right.tq b/deps/v8/src/builtins/array-reduce-right.tq index 33661c38d1..b1aa71b85b 100644 --- a/deps/v8/src/builtins/array-reduce-right.tq +++ b/deps/v8/src/builtins/array-reduce-right.tq @@ -4,8 +4,9 @@ namespace array { transitioning javascript builtin - ArrayReduceRightPreLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, length: Object): Object { + ArrayReduceRightPreLoopEagerDeoptContinuation( + js-implicit context: Context, + receiver: Object)(callback: Object, length: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -21,12 +22,13 @@ namespace array { // the hole. The continuation stub will search for the initial non-hole // element, rightly throwing an exception if not found. return ArrayReduceRightLoopContinuation( - jsreceiver, callbackfn, Hole, jsreceiver, 0, numberLength); + jsreceiver, callbackfn, TheHole, jsreceiver, 0, numberLength); } transitioning javascript builtin - ArrayReduceRightLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, initialK: Object, length: Object, + ArrayReduceRightLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, initialK: Object, length: Object, accumulator: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a @@ -45,27 +47,28 @@ namespace array { } transitioning javascript builtin - ArrayReduceRightLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, initialK: Object, length: Object, + ArrayReduceRightLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, initialK: Object, length: Object, result: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; const callbackfn = Cast<Callable>(callback) otherwise unreachable; - let numberK = Cast<Number>(initialK) otherwise unreachable; + const numberK = Cast<Number>(initialK) otherwise unreachable; const numberLength = Cast<Number>(length) otherwise unreachable; // The accumulator is the result from the callback call which just occured. - let r = ArrayReduceRightLoopContinuation( + const r = ArrayReduceRightLoopContinuation( jsreceiver, callbackfn, result, jsreceiver, numberK, numberLength); return r; } transitioning builtin ArrayReduceRightLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object, - o: JSReceiver, initialK: Number, length: Number): Object { + _receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object, + o: JSReceiver, initialK: Number, _length: Number): Object { let accumulator = initialAccumulator; // 8b and 9. Repeat, while k >= 0 @@ -82,7 +85,7 @@ namespace array { // 8b iii and 9c i. Let kValue be ? Get(O, Pk). const value: Object = GetProperty(o, k); - if (accumulator == Hole) { + if (accumulator == TheHole) { // 8b iii 1. accumulator = value; } else { @@ -99,7 +102,7 @@ namespace array { // 8c. if kPresent is false, throw a TypeError exception. // If the accumulator is discovered with the sentinel hole value, // this means kPresent is false. - if (accumulator == Hole) { + if (accumulator == TheHole) { ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduceRight'); } return accumulator; @@ -111,9 +114,9 @@ namespace array { labels Bailout(Number, Object) { let accumulator = initialAccumulator; const smiLen = Cast<Smi>(len) otherwise goto Bailout(len - 1, accumulator); - let fastO = - Cast<FastJSArray>(o) otherwise goto Bailout(len - 1, accumulator); - let fastOW = NewFastJSArrayWitness(fastO); + const fastO = Cast<FastJSArrayForRead>(o) + otherwise goto Bailout(len - 1, accumulator); + let fastOW = NewFastJSArrayForReadWitness(fastO); // Build a fast loop over the array. for (let k: Smi = smiLen - 1; k >= 0; k--) { @@ -123,7 +126,7 @@ namespace array { if (k >= fastOW.Get().length) goto Bailout(k, accumulator); const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; - if (accumulator == Hole) { + if (accumulator == TheHole) { accumulator = value; } else { accumulator = Call( @@ -131,7 +134,7 @@ namespace array { fastOW.Get()); } } - if (accumulator == Hole) { + if (accumulator == TheHole) { ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduceRight'); } return accumulator; @@ -139,12 +142,10 @@ namespace array { // https://tc39.github.io/ecma262/#sec-array.prototype.reduceRight transitioning javascript builtin - ArrayReduceRight(implicit context: Context)(receiver: Object, ...arguments): - Object { + ArrayReduceRight(js-implicit context: Context, receiver: Object)( + ...arguments): Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.reduceRight'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -162,7 +163,8 @@ namespace array { // exception. (This case is handled at the end of // ArrayReduceRightLoopContinuation). - const initialValue: Object = arguments.length > 1 ? arguments[1] : Hole; + const initialValue: Object = + arguments.length > 1 ? arguments[1] : TheHole; try { return FastArrayReduceRight(o, len, callbackfn, initialValue) @@ -176,8 +178,5 @@ namespace array { label NoCallableError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.reduceRight'); - } } } diff --git a/deps/v8/src/builtins/array-reduce.tq b/deps/v8/src/builtins/array-reduce.tq index 67a112fd41..a5f6feb9cc 100644 --- a/deps/v8/src/builtins/array-reduce.tq +++ b/deps/v8/src/builtins/array-reduce.tq @@ -4,8 +4,9 @@ namespace array { transitioning javascript builtin - ArrayReducePreLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, length: Object): Object { + ArrayReducePreLoopEagerDeoptContinuation( + js-implicit context: Context, + receiver: Object)(callback: Object, length: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -21,12 +22,13 @@ namespace array { // the hole. The continuation stub will search for the initial non-hole // element, rightly throwing an exception if not found. return ArrayReduceLoopContinuation( - jsreceiver, callbackfn, Hole, jsreceiver, 0, numberLength); + jsreceiver, callbackfn, TheHole, jsreceiver, 0, numberLength); } transitioning javascript builtin - ArrayReduceLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, initialK: Object, length: Object, + ArrayReduceLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, initialK: Object, length: Object, accumulator: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a @@ -45,25 +47,26 @@ namespace array { } transitioning javascript builtin - ArrayReduceLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, initialK: Object, length: Object, + ArrayReduceLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, initialK: Object, length: Object, result: Object): Object { // All continuation points in the optimized every implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; const callbackfn = Cast<Callable>(callback) otherwise unreachable; - let numberK = Cast<Number>(initialK) otherwise unreachable; + const numberK = Cast<Number>(initialK) otherwise unreachable; const numberLength = Cast<Number>(length) otherwise unreachable; // The accumulator is the result from the callback call which just occured. - let r = ArrayReduceLoopContinuation( + const r = ArrayReduceLoopContinuation( jsreceiver, callbackfn, result, jsreceiver, numberK, numberLength); return r; } transitioning builtin ArrayReduceLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object, + _receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object, o: JSReceiver, initialK: Number, length: Number): Object { let accumulator = initialAccumulator; @@ -81,7 +84,7 @@ namespace array { // 6c. i. Let kValue be ? Get(O, Pk). const value: Object = GetProperty(o, k); - if (accumulator == Hole) { + if (accumulator == TheHole) { // 8b. accumulator = value; } else { @@ -98,7 +101,7 @@ namespace array { // 8c. if kPresent is false, throw a TypeError exception. // If the accumulator is discovered with the sentinel hole value, // this means kPresent is false. - if (accumulator == Hole) { + if (accumulator == TheHole) { ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduce'); } return accumulator; @@ -110,9 +113,10 @@ namespace array { labels Bailout(Number, Object) { const k = 0; let accumulator = initialAccumulator; - const smiLen = Cast<Smi>(len) otherwise goto Bailout(k, accumulator); - let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k, accumulator); - let fastOW = NewFastJSArrayWitness(fastO); + Cast<Smi>(len) otherwise goto Bailout(k, accumulator); + const fastO = + Cast<FastJSArrayForRead>(o) otherwise goto Bailout(k, accumulator); + let fastOW = NewFastJSArrayForReadWitness(fastO); // Build a fast loop over the array. for (let k: Smi = 0; k < len; k++) { @@ -122,7 +126,7 @@ namespace array { if (k >= fastOW.Get().length) goto Bailout(k, accumulator); const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; - if (accumulator == Hole) { + if (accumulator == TheHole) { accumulator = value; } else { accumulator = Call( @@ -130,7 +134,7 @@ namespace array { fastOW.Get()); } } - if (accumulator == Hole) { + if (accumulator == TheHole) { ThrowTypeError(kReduceNoInitial, 'Array.prototype.reduce'); } return accumulator; @@ -138,12 +142,10 @@ namespace array { // https://tc39.github.io/ecma262/#sec-array.prototype.reduce transitioning javascript builtin - ArrayReduce(implicit context: Context)(receiver: Object, ...arguments): + ArrayReduce(js-implicit context: Context, receiver: Object)(...arguments): Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.reduce'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -161,7 +163,8 @@ namespace array { // exception. (This case is handled at the end of // ArrayReduceLoopContinuation). - const initialValue: Object = arguments.length > 1 ? arguments[1] : Hole; + const initialValue: Object = + arguments.length > 1 ? arguments[1] : TheHole; try { return FastArrayReduce(o, len, callbackfn, initialValue) @@ -175,8 +178,5 @@ namespace array { label NoCallableError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.reduce'); - } } } diff --git a/deps/v8/src/builtins/array-reverse.tq b/deps/v8/src/builtins/array-reverse.tq index f1ba8fddf7..82d2e6b605 100644 --- a/deps/v8/src/builtins/array-reverse.tq +++ b/deps/v8/src/builtins/array-reverse.tq @@ -165,7 +165,7 @@ namespace array_reverse { // https://tc39.github.io/ecma262/#sec-array.prototype.reverse transitioning javascript builtin ArrayPrototypeReverse( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { try { TryFastPackedArrayReverse(receiver) otherwise Baseline; return receiver; diff --git a/deps/v8/src/builtins/array-shift.tq b/deps/v8/src/builtins/array-shift.tq index 3c8c1491bb..4dd82d7b88 100644 --- a/deps/v8/src/builtins/array-shift.tq +++ b/deps/v8/src/builtins/array-shift.tq @@ -103,7 +103,7 @@ namespace array_shift { // https://tc39.github.io/ecma262/#sec-array.prototype.shift transitioning javascript builtin ArrayPrototypeShift( - implicit context: Context)(receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { try { return TryFastArrayShift(receiver, arguments) otherwise Slow; } diff --git a/deps/v8/src/builtins/array-slice.tq b/deps/v8/src/builtins/array-slice.tq index 5162329408..c3a6ac75cb 100644 --- a/deps/v8/src/builtins/array-slice.tq +++ b/deps/v8/src/builtins/array-slice.tq @@ -63,7 +63,7 @@ namespace array_slice { for (let current: Smi = start; current < to; ++current) { const e: Object = sloppyElements.objects[current + kSloppyArgumentsParameterMapStart]; - const newElement: Object = e != Hole ? + const newElement: Object = e != TheHole ? argumentsContext[UnsafeCast<Smi>(e)] : unmappedElements.objects[current]; // It is safe to skip the write barrier here because resultElements was @@ -105,7 +105,6 @@ namespace array_slice { return ExtractFastJSArray(context, a, start, count); } case (a: JSArgumentsObjectWithLength): { - const nativeContext: NativeContext = LoadNativeContext(context); const map: Map = a.map; if (IsFastAliasedArgumentsMap(map)) { return HandleFastAliasedSloppyArgumentsSlice(context, a, start, count) @@ -123,8 +122,8 @@ namespace array_slice { // https://tc39.github.io/ecma262/#sec-array.prototype.slice transitioning javascript builtin - ArrayPrototypeSlice(context: Context, receiver: Object, ...arguments): - Object { + ArrayPrototypeSlice(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // Handle array cloning case if the receiver is a fast array. if (arguments.length == 0) { typeswitch (receiver) { @@ -186,7 +185,7 @@ namespace array_slice { // 10. Repeat, while k < final while (k < final) { // a. Let Pk be ! ToString(k). - let pK: Number = k; + const pK: Number = k; // b. Let kPresent be ? HasProperty(O, Pk). const fromPresent: Boolean = HasProperty(o, pK); diff --git a/deps/v8/src/builtins/array-some.tq b/deps/v8/src/builtins/array-some.tq index f68ea4ac30..a30af4e47a 100644 --- a/deps/v8/src/builtins/array-some.tq +++ b/deps/v8/src/builtins/array-some.tq @@ -4,8 +4,9 @@ namespace array { transitioning javascript builtin - ArraySomeLoopEagerDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, + ArraySomeLoopEagerDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object): Object { // All continuation points in the optimized some implementation are // after the ToObject(O) call that ensures we are dealing with a @@ -25,9 +26,10 @@ namespace array { } transitioning javascript builtin - ArraySomeLoopLazyDeoptContinuation(implicit context: Context)( - receiver: Object, callback: Object, thisArg: Object, initialK: Object, - length: Object, result: Object): Object { + ArraySomeLoopLazyDeoptContinuation( + js-implicit context: Context, receiver: Object)( + callback: Object, thisArg: Object, initialK: Object, length: Object, + result: Object): Object { // All continuation points in the optimized some implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. @@ -51,9 +53,9 @@ namespace array { } transitioning builtin ArraySomeLoopContinuation(implicit context: Context)( - receiver: JSReceiver, callbackfn: Callable, thisArg: Object, - array: Object, o: JSReceiver, initialK: Number, length: Number, - initialTo: Object): Object { + _receiver: JSReceiver, callbackfn: Callable, thisArg: Object, + _array: Object, o: JSReceiver, initialK: Number, length: Number, + _initialTo: Object): Object { // 5. Let k be 0. // 6. Repeat, while k < len for (let k: Number = initialK; k < length; k++) { @@ -88,7 +90,7 @@ namespace array { labels Bailout(Smi) { let k: Smi = 0; const smiLen = Cast<Smi>(len) otherwise goto Bailout(k); - let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k); + const fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k); let fastOW = NewFastJSArrayWitness(fastO); // Build a fast loop over the smi array. @@ -109,11 +111,10 @@ namespace array { // https://tc39.github.io/ecma262/#sec-array.prototype.some transitioning javascript builtin - ArraySome(implicit context: Context)(receiver: Object, ...arguments): Object { + ArraySome(js-implicit context: Context, receiver: Object)(...arguments): + Object { try { - if (IsNullOrUndefined(receiver)) { - goto NullOrUndefinedError; - } + RequireObjectCoercible(receiver, 'Array.prototype.some'); // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject_Inline(context, receiver); @@ -143,8 +144,5 @@ namespace array { label TypeError deferred { ThrowTypeError(kCalledNonCallable, arguments[0]); } - label NullOrUndefinedError deferred { - ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.some'); - } } } diff --git a/deps/v8/src/builtins/array-splice.tq b/deps/v8/src/builtins/array-splice.tq index e24b51760c..3b65bb03d4 100644 --- a/deps/v8/src/builtins/array-splice.tq +++ b/deps/v8/src/builtins/array-splice.tq @@ -54,8 +54,7 @@ namespace array_splice { macro FastSplice<FixedArrayType: type, ElementType: type>(implicit context: Context)( args: Arguments, a: JSArray, length: Smi, newLength: Smi, - lengthDelta: Smi, actualStart: Smi, insertCount: Smi, - actualDeleteCount: Smi): void labels Bailout { + actualStart: Smi, insertCount: Smi, actualDeleteCount: Smi): void { // Make sure elements are writable. array::EnsureWriteableFastElements(a); @@ -77,7 +76,7 @@ namespace array_splice { UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count); } else { // Grow. - let capacity: Smi = CalculateNewElementsCapacity(newLength); + const capacity: Smi = CalculateNewElementsCapacity(newLength); const newElements: FixedArrayType = Extract<FixedArrayType>(elements, 0, actualStart, capacity); a.elements = newElements; @@ -168,12 +167,12 @@ namespace array_splice { if (IsFastSmiOrTaggedElementsKind(elementsKind)) { FastSplice<FixedArray, Object>( - args, a, length, newLength, lengthDelta, actualStart, insertCount, - actualDeleteCount) otherwise Bailout; + args, a, length, newLength, actualStart, insertCount, + actualDeleteCount); } else { FastSplice<FixedDoubleArray, Number>( - args, a, length, newLength, lengthDelta, actualStart, insertCount, - actualDeleteCount) otherwise Bailout; + args, a, length, newLength, actualStart, insertCount, + actualDeleteCount); } return deletedResult; @@ -301,8 +300,6 @@ namespace array_splice { context: Context, arguments: Arguments, o: JSReceiver, len: Number, actualStart: Number, insertCount: Smi, actualDeleteCount: Number): Object { - const affected: Number = len - actualStart - actualDeleteCount; - // 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). const a: JSReceiver = ArraySpeciesCreate(context, o, actualDeleteCount); const itemCount: Number = insertCount; @@ -353,8 +350,8 @@ namespace array_splice { // https://tc39.github.io/ecma262/#sec-array.prototype.splice transitioning javascript builtin - ArrayPrototypeSplice(context: Context, receiver: Object, ...arguments): - Object { + ArrayPrototypeSplice(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // 1. Let O be ? ToObject(this value). const o: JSReceiver = ToObject(context, receiver); diff --git a/deps/v8/src/builtins/array-unshift.tq b/deps/v8/src/builtins/array-unshift.tq index b2e746db47..e685d520cd 100644 --- a/deps/v8/src/builtins/array-unshift.tq +++ b/deps/v8/src/builtins/array-unshift.tq @@ -93,7 +93,7 @@ namespace array_unshift { // https://tc39.github.io/ecma262/#sec-array.prototype.unshift transitioning javascript builtin ArrayPrototypeUnshift( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { try { TryFastArrayUnshift(context, receiver, arguments) otherwise Baseline; } diff --git a/deps/v8/src/builtins/array.tq b/deps/v8/src/builtins/array.tq index 9807db19c6..7e044e086b 100644 --- a/deps/v8/src/builtins/array.tq +++ b/deps/v8/src/builtins/array.tq @@ -33,18 +33,19 @@ namespace array { } macro IsJSArray(implicit context: Context)(o: Object): bool { - try { - const array: JSArray = Cast<JSArray>(o) otherwise NotArray; - return true; - } - label NotArray { - return false; + typeswitch (o) { + case (JSArray): { + return true; + } + case (Object): { + return false; + } } } macro LoadElementOrUndefined(a: FixedArray, i: Smi): Object { const e: Object = a.objects[i]; - return e == Hole ? Undefined : e; + return e == TheHole ? Undefined : e; } macro LoadElementOrUndefined(a: FixedDoubleArray, i: Smi): NumberOrUndefined { @@ -62,26 +63,7 @@ namespace array { } macro StoreArrayHole(elements: FixedArray, k: Smi): void { - elements.objects[k] = Hole; - } - - macro CopyArrayElement( - elements: FixedArray, newElements: FixedArray, from: Smi, to: Smi): void { - const e: Object = elements.objects[from]; - newElements.objects[to] = e; - } - - macro CopyArrayElement( - elements: FixedDoubleArray, newElements: FixedDoubleArray, from: Smi, - to: Smi): void { - try { - const floatValue: float64 = LoadDoubleWithHoleCheck(elements, from) - otherwise FoundHole; - newElements.floats[to] = floatValue; - } - label FoundHole { - StoreArrayHole(newElements, to); - } + elements.objects[k] = TheHole; } extern macro SetPropertyLength(implicit context: Context)(Object, Number); diff --git a/deps/v8/src/builtins/base.tq b/deps/v8/src/builtins/base.tq index 76e1a486c8..4aa1d57837 100644 --- a/deps/v8/src/builtins/base.tq +++ b/deps/v8/src/builtins/base.tq @@ -14,9 +14,11 @@ #include 'src/objects/js-generator.h' #include 'src/objects/js-promise.h' #include 'src/objects/js-regexp-string-iterator.h' -#include 'src/objects/module.h' +#include 'src/objects/js-weak-refs.h' #include 'src/objects/objects.h' +#include 'src/objects/source-text-module.h' #include 'src/objects/stack-frame-info.h' +#include 'src/objects/synthetic-module.h' #include 'src/objects/template-objects.h' type void; @@ -31,12 +33,16 @@ type PositiveSmi extends Smi; // The Smi value zero, which is often used as null for HeapObject types. type Zero extends PositiveSmi; +// A value with the size of Tagged which may contain arbitrary data. +type Uninitialized extends Tagged; + @abstract extern class HeapObject extends Tagged { map: Map; } type Object = Smi | HeapObject; + type int32 generates 'TNode<Int32T>' constexpr 'int32_t'; type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t'; type int31 extends int32 @@ -84,32 +90,33 @@ extern class Oddball extends HeapObject { extern class HeapNumber extends HeapObject { value: float64; } type Number = Smi | HeapNumber; -type BigInt extends HeapObject generates 'TNode<BigInt>'; type Numeric = Number | BigInt; @abstract -@noVerifier +@generateCppClass extern class Name extends HeapObject { - hash_field: int32; + hash_field: uint32; } +@generateCppClass extern class Symbol extends Name { flags: int32; - name: Object; + name: Object; // The print name of a symbol, or undefined if none. } @abstract +@generateCppClass extern class String extends Name { - length: uint32; + length: int32; } +@generateCppClass extern class ConsString extends String { first: String; second: String; } @abstract -@noVerifier extern class ExternalString extends String { resource: RawPtr; resource_data: RawPtr; @@ -118,28 +125,37 @@ extern class ExternalString extends String { extern class ExternalOneByteString extends ExternalString {} extern class ExternalTwoByteString extends ExternalString {} -extern class InternalizedString extends String {} +@generateCppClass +extern class InternalizedString extends String { +} // TODO(v8:8983): Add declaration for variable-sized region. @abstract -@noVerifier +@generateCppClass extern class SeqString extends String { } -extern class SeqOneByteString extends SeqString {} -extern class SeqTwoByteString extends SeqString {} +@generateCppClass +extern class SeqOneByteString extends SeqString { +} +@generateCppClass +extern class SeqTwoByteString extends SeqString { +} +@generateCppClass extern class SlicedString extends String { parent: String; offset: Smi; } -extern class ThinString extends String { actual: String; } +@generateCppClass +extern class ThinString extends String { + actual: String; +} // The HeapNumber value NaN type NaN extends HeapNumber; @abstract -@noVerifier @generatePrint @generateCppClass extern class Struct extends HeapObject { @@ -169,7 +185,6 @@ type DirectString extends String; type RootIndex generates 'TNode<Int32T>' constexpr 'RootIndex'; @abstract -@noVerifier @generateCppClass extern class FixedArrayBase extends HeapObject { length: Smi; @@ -190,9 +205,7 @@ type LayoutDescriptor extends ByteArray type TransitionArray extends WeakFixedArray generates 'TNode<TransitionArray>'; -// InstanceType actually extends uint16, but a bunch of methods in -// CodeStubAssembler expect a TNode<Int32T>, so keeping it signed for now. -type InstanceType extends int16 constexpr 'InstanceType'; +type InstanceType extends uint16 constexpr 'InstanceType'; extern class Map extends HeapObject { instance_size_in_words: uint8; @@ -214,19 +227,21 @@ extern class Map extends HeapObject { @ifnot(V8_DOUBLE_FIELDS_UNBOXING) layout_descriptor: void; dependent_code: DependentCode; prototype_validity_cell: Smi | Cell; + // TODO(v8:9108): Misusing "weak" keyword; type should be + // Map | Weak<Map> | TransitionArray | PrototypeInfo | Smi. weak transitions_or_prototype_info: Map | TransitionArray | PrototypeInfo | Smi; } -type BytecodeArray extends FixedArrayBase; - @generatePrint +@generateCppClass extern class EnumCache extends Struct { keys: FixedArray; indices: FixedArray; } @generatePrint +@generateCppClass extern class SourcePositionTableWithFrameCache extends Struct { source_position_table: ByteArray; stack_frame_cache: Object; @@ -250,8 +265,7 @@ extern class DescriptorArray extends HeapObject { // than building the definition from C++. intrinsic %GetAllocationBaseSize<Class: type>(map: Map): intptr; intrinsic %Allocate<Class: type>(size: intptr): Class; -intrinsic %AllocateInternalClass<Class: type>(slotCount: constexpr intptr): - Class; +intrinsic %GetStructMap(instanceKind: constexpr InstanceType): Map; intrinsic %AddIndexedFieldSizeToObjectSize<T: type>( baseSize: intptr, indexSize: T, fieldSize: int32): intptr { @@ -282,24 +296,35 @@ intrinsic } @abstract -@noVerifier extern class JSReceiver extends HeapObject { - properties_or_hash: FixedArrayBase | Smi; + properties_or_hash: FixedArrayBase | PropertyArray | Smi; } type Constructor extends JSReceiver; @abstract @dirtyInstantiatedAbstractClass +@generateCppClass extern class JSObject extends JSReceiver { - @noVerifier elements: FixedArrayBase; + // [elements]: The elements (properties with names that are integers). + // + // Elements can be in two general modes: fast and slow. Each mode + // corresponds to a set of object representations of elements that + // have something in common. + // + // In the fast mode elements is a FixedArray and so each element can be + // quickly accessed. The elements array can have one of several maps in this + // mode: fixed_array_map, fixed_double_array_map, + // sloppy_arguments_elements_map or fixed_cow_array_map (for copy-on-write + // arrays). In the latter case the elements array may be shared by a few + // objects and so before writing to any element the array must be copied. Use + // EnsureWritableFastElements in this case. + // + // In the slow mode the elements is either a NumberDictionary or a + // FixedArray parameter map for a (sloppy) arguments object. + elements: FixedArrayBase; } -macro NewJSObject( - map: Map, properties: FixedArrayBase | Smi, - elements: FixedArrayBase): JSObject { - return new JSObject{map, properties_or_hash: properties, elements}; -} macro NewJSObject(implicit context: Context)(): JSObject { const objectFunction: JSFunction = GetObjectFunction(); const map: Map = Cast<Map>(objectFunction.prototype_or_initial_map) @@ -328,19 +353,33 @@ macro GetDerivedMap(implicit context: Context)( } } +macro AllocateFastOrSlowJSObjectFromMap(implicit context: Context)(map: Map): + JSObject { + let properties = kEmptyFixedArray; + if (IsDictionaryMap(map)) { + properties = AllocateNameDictionary(kNameDictionaryInitialCapacity); + } + return AllocateJSObjectFromMap( + map, properties, kEmptyFixedArray, kNone, kWithSlackTracking); +} + extern class JSFunction extends JSObject { shared_function_info: SharedFunctionInfo; context: Context; feedback_cell: FeedbackCell; weak code: Code; + + // Space for the following field may or may not be allocated. @noVerifier weak prototype_or_initial_map: JSReceiver | Map; } +@generateCppClass extern class JSProxy extends JSReceiver { - target: Object; - handler: Object; + target: JSReceiver | Null; + handler: JSReceiver | Null; } +// Just a starting shape for JSObject; properties can move after initialization. @noVerifier extern class JSProxyRevocableResult extends JSObject { proxy: Object; @@ -358,21 +397,39 @@ macro NewJSProxyRevocableResult(implicit context: Context)( }; } -extern class JSGlobalProxy extends JSObject { native_context: Object; } +@generateCppClass +extern class JSGlobalProxy extends JSObject { + // [native_context]: the owner native context of this global proxy object. + // It is null value if this object is not used by any context. + native_context: Object; +} -extern class JSValue extends JSObject { value: Object; } +@generateCppClass +extern class JSPrimitiveWrapper extends JSObject { + value: Object; +} extern class JSArgumentsObject extends JSObject {} + +// Just a starting shape for JSObject; properties can move after initialization. @noVerifier @hasSameInstanceTypeAsParent extern class JSArgumentsObjectWithLength extends JSArgumentsObject { length: Object; } + +// Just a starting shape for JSObject; properties can move after initialization. @hasSameInstanceTypeAsParent extern class JSSloppyArgumentsObject extends JSArgumentsObjectWithLength { callee: Object; } +// Just a starting shape for JSObject; properties can move after initialization. +@hasSameInstanceTypeAsParent +@noVerifier +extern class JSStrictArgumentsObject extends JSArgumentsObjectWithLength { +} + extern class JSArrayIterator extends JSObject { iterated_object: JSReceiver; next_index: Number; @@ -405,20 +462,6 @@ macro NewJSArray(implicit context: Context)(): JSArray { }; } -struct HoleIterator { - Next(): Object labels NoMore() { - return Hole; - } -} - -macro NewJSArray(implicit context: Context)(map: Map, length: Smi): JSArray { - const map = GetFastPackedSmiElementsJSArrayMap(); - const i = HoleIterator{}; - const elements = new FixedArray{map, length, objects: ...i}; - return new - JSArray{map, properties_or_hash: kEmptyFixedArray, elements, length}; -} - // A HeapObject with a JSArray map, and either fast packed elements, or fast // holey elements when the global NoElementsProtector is not invalidated. transient type FastJSArray extends JSArray; @@ -441,18 +484,61 @@ transient type FastJSArrayForReadWithNoCustomIteration extends type NoSharedNameSentinel extends Smi; -type JSModuleNamespace extends JSObject; -type WeakArrayList extends HeapObject; +@generateCppClass +extern class CallHandlerInfo extends Struct { + callback: Foreign | Undefined; + js_callback: Foreign | Undefined; + data: Object; +} + +type ObjectHashTable extends FixedArray; @abstract +extern class Module extends HeapObject { + exports: ObjectHashTable; + hash: Smi; + status: Smi; + module_namespace: JSModuleNamespace | Undefined; + exception: Object; +} + +type SourceTextModuleInfo extends FixedArray; + +extern class SourceTextModule extends Module { + code: SharedFunctionInfo | JSFunction | + JSGeneratorObject | SourceTextModuleInfo; + regular_exports: FixedArray; + regular_imports: FixedArray; + requested_modules: FixedArray; + script: Script; + import_meta: TheHole | JSObject; + dfs_index: Smi; + dfs_ancestor_index: Smi; +} + +extern class SyntheticModule extends Module { + name: String; + export_names: FixedArray; + evaluation_steps: Foreign; +} + +@abstract +extern class JSModuleNamespace extends JSObject { + module: Module; +} + +@hasSameInstanceTypeAsParent @noVerifier +extern class TemplateList extends FixedArray { +} + +@abstract extern class JSWeakCollection extends JSObject { table: Object; } extern class JSWeakSet extends JSWeakCollection {} extern class JSWeakMap extends JSWeakCollection {} -@noVerifier extern class JSCollectionIterator extends JSObject { table: Object; index: Object; @@ -474,12 +560,20 @@ extern class JSMessageObject extends JSObject { error_level: Smi; } +extern class WeakArrayList extends HeapObject { + capacity: Smi; + length: Smi; + // TODO(v8:8983): declare variable-sized region for contained MaybeObject's + // objects[length]: MaybeObject; +} + extern class PrototypeInfo extends Struct { js_module_namespace: JSModuleNamespace | Undefined; prototype_users: WeakArrayList | Zero; registry_slot: Smi; validity_cell: Object; - @noVerifier object_create_map: Smi | WeakArrayList; + // TODO(v8:9108): Should be Weak<Map> | Undefined. + @noVerifier object_create_map: Map | Undefined; bit_field: Smi; } @@ -503,7 +597,7 @@ extern class Script extends Struct { extern class EmbedderDataArray extends HeapObject { length: Smi; } -type ScopeInfo extends Object generates 'TNode<ScopeInfo>'; +type ScopeInfo extends HeapObject generates 'TNode<ScopeInfo>'; extern class PreparseData extends HeapObject { // TODO(v8:8983): Add declaration for variable-sized region. @@ -527,16 +621,30 @@ extern class SharedFunctionInfo extends HeapObject { expected_nof_properties: uint16; function_token_offset: int16; flags: int32; + function_literal_id: int32; @if(V8_SFI_HAS_UNIQUE_ID) unique_id: int32; } extern class JSBoundFunction extends JSObject { - bound_target_function: JSReceiver; + bound_target_function: Callable; bound_this: Object; bound_arguments: FixedArray; } -type Callable = JSFunction | JSBoundFunction | JSProxy; +// Specialized types. The following three type definitions don't correspond to +// actual C++ classes, but have Is... methods that check additional constraints. + +// A Foreign object whose raw pointer is not allowed to be null. +type NonNullForeign extends Foreign; + +// A function built with InstantiateFunction for the public API. +type CallableApiObject extends HeapObject; + +// A JSProxy with the callable bit set. +type CallableJSProxy extends JSProxy; + +type Callable = + JSFunction | JSBoundFunction | CallableJSProxy | CallableApiObject; extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength( FixedArrayBase): intptr; @@ -547,7 +655,7 @@ type NumberDictionary extends HeapObject extern class FreeSpace extends HeapObject { size: Smi; - @noVerifier next: FreeSpace; + next: FreeSpace | Uninitialized; } // %RawDownCast should *never* be used anywhere in Torque code except for @@ -609,45 +717,12 @@ extern class JSArrayBufferView extends JSObject { } extern class JSTypedArray extends JSArrayBufferView { - AttachOffHeapBuffer(buffer: JSArrayBuffer, byteOffset: uintptr): void { - const basePointer: Smi = 0; - - // The max byteOffset is 8 * MaxSmi on the particular platform. 32 bit - // platforms are self-limiting, because we can't allocate an array bigger - // than our 32-bit arithmetic range anyway. 64 bit platforms could - // theoretically have an offset up to 2^35 - 1. - const backingStore = buffer.backing_store; - const externalPointer = backingStore + Convert<intptr>(byteOffset); - - // Assert no overflow has occurred. Only assert if the mock array buffer - // allocator is NOT used. When the mock array buffer is used, impossibly - // large allocations are allowed that would erroneously cause an overflow - // and this assertion to fail. - assert( - IsMockArrayBufferAllocatorFlag() || - Convert<uintptr>(externalPointer) >= Convert<uintptr>(backingStore)); - - this.elements = kEmptyByteArray; - this.buffer = buffer; - this.external_pointer = externalPointer; - this.base_pointer = basePointer; - } - length: uintptr; external_pointer: RawPtr; base_pointer: ByteArray | Smi; } -@noVerifier -extern class JSAccessorPropertyDescriptor extends JSObject { - get: Object; - set: Object; - enumerable: Object; - configurable: Object; -} - @abstract -@noVerifier extern class JSCollection extends JSObject { table: Object; } @@ -681,14 +756,6 @@ extern class JSStringIterator extends JSObject { next_index: Smi; } -@noVerifier -extern class JSDataPropertyDescriptor extends JSObject { - value: Object; - writable: Object; - enumerable: Object; - configurable: Object; -} - @abstract extern class TemplateInfo extends Struct { tag: Object; @@ -722,7 +789,7 @@ extern class FunctionTemplateInfo extends TemplateInfo { function_template_rare_data: Object; shared_function_info: Object; flag: Smi; - @noVerifier length: Smi; + length: Smi; cached_property_name: Object; } @@ -749,8 +816,6 @@ type LanguageMode extends Smi constexpr 'LanguageMode'; type ExtractFixedArrayFlags generates 'TNode<Smi>' constexpr 'CodeStubAssembler::ExtractFixedArrayFlags'; -type ParameterMode - generates 'TNode<Int32T>' constexpr 'ParameterMode'; type WriteBarrierMode generates 'TNode<Int32T>' constexpr 'WriteBarrierMode'; @@ -770,21 +835,21 @@ const UTF32: extern class Foreign extends HeapObject { foreign_address: RawPtr; } extern class InterceptorInfo extends Struct { - @noVerifier getter: Foreign | Zero; - @noVerifier setter: Foreign | Zero; - @noVerifier query: Foreign | Zero; - @noVerifier descriptor: Foreign | Zero; - @noVerifier deleter: Foreign | Zero; - @noVerifier enumerator: Foreign | Zero; - @noVerifier definer: Foreign | Zero; + getter: NonNullForeign | Zero | Undefined; + setter: NonNullForeign | Zero | Undefined; + query: NonNullForeign | Zero | Undefined; + descriptor: NonNullForeign | Zero | Undefined; + deleter: NonNullForeign | Zero | Undefined; + enumerator: NonNullForeign | Zero | Undefined; + definer: NonNullForeign | Zero | Undefined; data: Object; flags: Smi; } extern class AccessCheckInfo extends Struct { - callback: Foreign | Zero; - named_interceptor: InterceptorInfo | Zero; - indexed_interceptor: InterceptorInfo | Zero; + callback: Foreign | Zero | Undefined; + named_interceptor: InterceptorInfo | Zero | Undefined; + indexed_interceptor: InterceptorInfo | Zero | Undefined; data: Object; } @@ -800,6 +865,9 @@ extern class Cell extends HeapObject { value: Object; } extern class DataHandler extends Struct { smi_handler: Smi | Code; validity_cell: Smi | Cell; + + // Space for the following fields may or may not be allocated. + // TODO(v8:9108): Misusing "weak" keyword; should be MaybeObject. @noVerifier weak data_1: Object; @noVerifier weak data_2: Object; @noVerifier weak data_3: Object; @@ -850,17 +918,22 @@ extern class StackFrameInfo extends Struct { column_number: Smi; promise_all_index: Smi; script_id: Smi; - script_name: Object; - script_name_or_source_url: Object; - function_name: Object; - wasm_module_name: Object; + script_name: String | Null | Undefined; + script_name_or_source_url: String | Null | Undefined; + function_name: String | Null | Undefined; + method_name: String | Null | Undefined; + type_name: String | Null | Undefined; + eval_origin: String | Null | Undefined; + wasm_module_name: String | Null | Undefined; flag: Smi; } +type FrameArray extends FixedArray; + extern class StackTraceFrame extends Struct { - frame_array: Object; + frame_array: FrameArray | Undefined; frame_index: Smi; - frame_info: Object; + frame_info: StackFrameInfo | Undefined; id: Smi; } @@ -876,9 +949,20 @@ extern class WasmExportedFunctionData extends Struct { instance: WasmInstanceObject; jump_table_offset: Smi; function_index: Smi; + // The remaining fields are for fast calling from C++. The contract is + // that they are lazily populated, and either all will be present or none. + c_wrapper_code: Object; + wasm_call_target: Smi; // Pseudo-smi: one-bit shift on all platforms. + packed_args_size: Smi; } -extern class WasmJSFunctionData extends Struct { wrapper_code: Code; } +extern class WasmJSFunctionData extends Struct { + callable: JSReceiver; + wrapper_code: Code; + serialized_return_count: Smi; + serialized_parameter_count: Smi; + serialized_signature: ByteArray; // PodArray<wasm::ValueType> +} extern class WasmCapiFunctionData extends Struct { call_target: RawPtr; @@ -887,6 +971,16 @@ extern class WasmCapiFunctionData extends Struct { serialized_signature: ByteArray; // PodArray<wasm::ValueType> } +extern class WasmIndirectFunctionTable extends Struct { + size: uint32; + @if(TAGGED_SIZE_8_BYTES) optional_padding: uint32; + @ifnot(TAGGED_SIZE_8_BYTES) optional_padding: void; + sig_ids: RawPtr; + targets: RawPtr; + managed_native_allocations: Foreign | Undefined; + refs: FixedArray; +} + extern class WasmDebugInfo extends Struct { instance: WasmInstanceObject; interpreter_handle: Foreign | Undefined; @@ -947,9 +1041,9 @@ const kAllowLargeObjectAllocation: constexpr AllocationFlags generates 'CodeStubAssembler::kAllowLargeObjectAllocation'; const kWithSlackTracking: constexpr SlackTrackingMode - generates 'SlackTrackingMode::kWithSlackTracking'; + generates 'CodeStubAssembler::SlackTrackingMode::kWithSlackTracking'; const kNoSlackTracking: constexpr SlackTrackingMode - generates 'SlackTrackingMode::kNoSlackTracking'; + generates 'CodeStubAssembler::SlackTrackingMode::kNoSlackTracking'; const kFixedDoubleArrays: constexpr ExtractFixedArrayFlags generates 'CodeStubAssembler::ExtractFixedArrayFlag::kFixedDoubleArrays'; @@ -977,6 +1071,8 @@ const kCalledNonCallable: constexpr MessageTemplate generates 'MessageTemplate::kCalledNonCallable'; const kCalledOnNullOrUndefined: constexpr MessageTemplate generates 'MessageTemplate::kCalledOnNullOrUndefined'; +const kProtoObjectOrNull: constexpr MessageTemplate + generates 'MessageTemplate::kProtoObjectOrNull'; const kInvalidOffset: constexpr MessageTemplate generates 'MessageTemplate::kInvalidOffset'; const kInvalidTypedArrayLength: constexpr MessageTemplate @@ -1003,13 +1099,17 @@ const kSymbolToString: constexpr MessageTemplate generates 'MessageTemplate::kSymbolToString'; const kPropertyNotFunction: constexpr MessageTemplate generates 'MessageTemplate::kPropertyNotFunction'; +const kBigIntMaxLength: constexpr intptr + generates 'BigInt::kMaxLength'; +const kBigIntTooBig: constexpr MessageTemplate + generates 'MessageTemplate::kBigIntTooBig'; const kMaxArrayIndex: constexpr uint32 generates 'JSArray::kMaxArrayIndex'; const kArrayBufferMaxByteLength: constexpr uintptr generates 'JSArrayBuffer::kMaxByteLength'; -const V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP: - constexpr int31 generates 'V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP'; +const kMaxTypedArrayInHeap: + constexpr int31 generates 'JSTypedArray::kMaxSizeInHeap'; const kMaxSafeInteger: constexpr float64 generates 'kMaxSafeInteger'; const kSmiMaxValue: constexpr uintptr generates 'kSmiMaxValue'; const kSmiMax: uintptr = kSmiMaxValue; @@ -1054,7 +1154,13 @@ const kStrictReadOnlyProperty: constexpr MessageTemplate const kString: constexpr PrimitiveType generates 'PrimitiveType::kString'; -type Hole extends Oddball; +const kExternalPointerForOnHeapArray: constexpr RawPtr + generates 'JSTypedArray::ExternalPointerForOnHeapArray()'; + +const kNameDictionaryInitialCapacity: + constexpr int32 generates 'NameDictionary::kInitialCapacity'; + +type TheHole extends Oddball; type Null extends Oddball; type Undefined extends Oddball; type True extends Oddball; @@ -1064,7 +1170,7 @@ type Boolean = True | False; type NumberOrUndefined = Number | Undefined; -extern macro TheHoleConstant(): Hole; +extern macro TheHoleConstant(): TheHole; extern macro NullConstant(): Null; extern macro UndefinedConstant(): Undefined; extern macro TrueConstant(): True; @@ -1075,7 +1181,7 @@ extern macro EmptyStringConstant(): EmptyString; extern macro LengthStringConstant(): String; extern macro NanConstant(): NaN; -const Hole: Hole = TheHoleConstant(); +const TheHole: TheHole = TheHoleConstant(); const Null: Null = NullConstant(); const Undefined: Undefined = UndefinedConstant(); const True: True = TrueConstant(); @@ -1090,11 +1196,6 @@ const false: constexpr bool generates 'false'; const kStrict: constexpr LanguageMode generates 'LanguageMode::kStrict'; const kSloppy: constexpr LanguageMode generates 'LanguageMode::kSloppy'; -const SMI_PARAMETERS: constexpr ParameterMode - generates 'CodeStubAssembler::SMI_PARAMETERS'; -const INTPTR_PARAMETERS: constexpr ParameterMode - generates 'CodeStubAssembler::INTPTR_PARAMETERS'; - const SKIP_WRITE_BARRIER: constexpr WriteBarrierMode generates 'SKIP_WRITE_BARRIER'; const UNSAFE_SKIP_WRITE_BARRIER: @@ -1107,7 +1208,7 @@ extern class AsyncGeneratorRequest extends Struct { promise: JSPromise; } -extern class ModuleInfoEntry extends Struct { +extern class SourceTextModuleInfoEntry extends Struct { export_name: String | Undefined; local_name: String | Undefined; import_name: String | Undefined; @@ -1134,7 +1235,7 @@ extern class PromiseReaction extends Struct { extern class PromiseReactionJobTask extends Microtask { argument: Object; context: Context; - @noVerifier handler: Callable | Undefined; + handler: Callable | Undefined; promise_or_capability: JSPromise | PromiseCapability | Undefined; } @@ -1155,22 +1256,8 @@ extern class JSRegExp extends JSObject { flags: Smi | Undefined; } -@noVerifier -extern class JSIteratorResult extends JSObject { - value: Object; - done: Boolean; -} - -macro NewJSIteratorResult(implicit context: Context)( - value: Object, done: Boolean): JSIteratorResult { - return new JSIteratorResult{ - map: GetIteratorResultMap(), - properties_or_hash: kEmptyFixedArray, - elements: kEmptyFixedArray, - value, - done - }; -} +extern transitioning macro AllocateJSIteratorResult(implicit context: Context)( + Object, Boolean): JSObject; // Note: Although a condition for a FastJSRegExp is having a positive smi // lastIndex (see RegExpBuiltinsAssembler::BranchIfFastRegExp), it is possible @@ -1230,9 +1317,9 @@ extern class AccessorInfo extends Struct { name: Object; flags: Smi; expected_receiver_type: Object; - @noVerifier setter: Foreign | Zero; - @noVerifier getter: Foreign | Zero; - @noVerifier js_getter: Foreign | Zero; + setter: NonNullForeign | Zero; + getter: NonNullForeign | Zero; + js_getter: NonNullForeign | Zero; data: Object; } @@ -1277,7 +1364,7 @@ extern class FeedbackCell extends Struct { type AllocationSite extends Struct; extern class AllocationMemento extends Struct { - @noVerifier allocation_site: AllocationSite; + allocation_site: AllocationSite; } extern class WasmModuleObject extends JSObject { @@ -1303,8 +1390,8 @@ extern class WasmMemoryObject extends JSObject { } extern class WasmGlobalObject extends JSObject { - untagged_buffer: JSArrayBuffer; - tagged_buffer: FixedArray; + untagged_buffer: JSArrayBuffer | Undefined; + tagged_buffer: FixedArray | Undefined; offset: Smi; flags: Smi; } @@ -1314,10 +1401,6 @@ extern class WasmExceptionObject extends JSObject { exception_tag: HeapObject; } -@noVerifier -extern class WasmExceptionPackage extends JSReceiver { -} - type WasmExportedFunction extends JSFunction; extern class AsmWasmData extends Struct { @@ -1327,6 +1410,46 @@ extern class AsmWasmData extends Struct { uses_bitset: HeapNumber; } +extern class JSFinalizationGroup extends JSObject { + native_context: NativeContext; + cleanup: Object; + active_cells: Undefined | WeakCell; + cleared_cells: Undefined | WeakCell; + key_map: Object; + next: Undefined | JSFinalizationGroup; + flags: Smi; +} + +extern class JSFinalizationGroupCleanupIterator extends JSObject { + finalization_group: JSFinalizationGroup; +} + +extern class WeakCell extends HeapObject { + finalization_group: Undefined | JSFinalizationGroup; + target: Undefined | JSReceiver; + holdings: Object; + prev: Undefined | WeakCell; + next: Undefined | WeakCell; + key: Object; + key_list_prev: Undefined | WeakCell; + key_list_next: Undefined | WeakCell; +} + +extern class JSWeakRef extends JSObject { target: Undefined | JSReceiver; } + +extern class BytecodeArray extends FixedArrayBase { + // TODO(v8:8983): bytecode array object sizes vary based on their contents. + constant_pool: FixedArray; + handler_table: ByteArray; + source_position_table: Undefined | ByteArray | + SourcePositionTableWithFrameCache; + frame_size: int32; + parameter_size: int32; + incoming_new_target_or_generator_register: int32; + osr_nesting_level: int8; + bytecode_age: int8; +} + extern macro Is64(): constexpr bool; extern macro SelectBooleanConstant(bool): Boolean; @@ -1358,7 +1481,7 @@ extern transitioning builtin SetProperty(implicit context: Context)( extern transitioning builtin SetPropertyInLiteral(implicit context: Context)( Object, Object, Object); extern transitioning builtin DeleteProperty(implicit context: Context)( - Object, Object, LanguageMode); + Object, Object, LanguageMode): Object; extern transitioning builtin HasProperty(implicit context: Context)( Object, Object): Boolean; extern transitioning macro HasProperty_Inline(implicit context: Context)( @@ -1403,6 +1526,10 @@ extern macro ConstructWithTarget(implicit context: Context)( extern macro SpeciesConstructor(implicit context: Context)( Object, JSReceiver): JSReceiver; +extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool; +extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32): + NameDictionary; + extern builtin ToObject(Context, Object): JSReceiver; extern macro ToObject_Inline(Context, Object): JSReceiver; extern macro IsNullOrUndefined(Object): bool; @@ -1598,6 +1725,7 @@ extern operator '==' macro Word32Equal(bool, bool): bool; extern operator '!=' macro Word32NotEqual(bool, bool): bool; extern operator '+' macro Float64Add(float64, float64): float64; +extern operator '-' macro Float64Sub(float64, float64): float64; extern operator '+' macro NumberAdd(Number, Number): Number; extern operator '-' macro NumberSub(Number, Number): Number; @@ -1650,6 +1778,8 @@ extern macro TaggedIsNotSmi(Object): bool; extern macro TaggedIsPositiveSmi(Object): bool; extern macro IsValidPositiveSmi(intptr): bool; +extern macro IsInteger(HeapNumber): bool; + extern macro HeapObjectToJSDataView(HeapObject): JSDataView labels CastError; extern macro HeapObjectToJSProxy(HeapObject): JSProxy @@ -1713,7 +1843,7 @@ macro Cast<A: type>(o: HeapObject): A labels CastError; Cast<HeapObject>(o: HeapObject): HeapObject - labels CastError { +labels _CastError { return o; } @@ -1837,6 +1967,11 @@ Cast<HeapNumber>(o: HeapObject): HeapNumber goto CastError; } +Cast<BigInt>(o: HeapObject): BigInt labels CastError { + if (IsBigInt(o)) return %RawDownCast<BigInt>(o); + goto CastError; +} + Cast<JSRegExp>(o: HeapObject): JSRegExp labels CastError { if (IsJSRegExp(o)) return %RawDownCast<JSRegExp>(o); @@ -1849,9 +1984,9 @@ Cast<Map>(implicit context: Context)(o: HeapObject): Map goto CastError; } -Cast<JSValue>(o: HeapObject): JSValue +Cast<JSPrimitiveWrapper>(o: HeapObject): JSPrimitiveWrapper labels CastError { - if (IsJSValue(o)) return %RawDownCast<JSValue>(o); + if (IsJSPrimitiveWrapper(o)) return %RawDownCast<JSPrimitiveWrapper>(o); goto CastError; } @@ -1915,24 +2050,24 @@ Cast<FastJSArrayForCopy>(implicit context: Context)(o: HeapObject): FastJSArrayForCopy labels CastError { if (IsArraySpeciesProtectorCellInvalid()) goto CastError; - const a: FastJSArray = Cast<FastJSArray>(o) otherwise CastError; - return %RawDownCast<FastJSArrayForCopy>(o); + const a = Cast<FastJSArray>(o) otherwise CastError; + return %RawDownCast<FastJSArrayForCopy>(a); } Cast<FastJSArrayWithNoCustomIteration>(implicit context: Context)( o: HeapObject): FastJSArrayWithNoCustomIteration labels CastError { if (IsArrayIteratorProtectorCellInvalid()) goto CastError; - const a: FastJSArray = Cast<FastJSArray>(o) otherwise CastError; - return %RawDownCast<FastJSArrayWithNoCustomIteration>(o); + const a = Cast<FastJSArray>(o) otherwise CastError; + return %RawDownCast<FastJSArrayWithNoCustomIteration>(a); } Cast<FastJSArrayForReadWithNoCustomIteration>(implicit context: Context)( o: HeapObject): FastJSArrayForReadWithNoCustomIteration labels CastError { if (IsArrayIteratorProtectorCellInvalid()) goto CastError; - const a: FastJSArrayForRead = Cast<FastJSArrayForRead>(o) otherwise CastError; - return %RawDownCast<FastJSArrayForReadWithNoCustomIteration>(o); + const a = Cast<FastJSArrayForRead>(o) otherwise CastError; + return %RawDownCast<FastJSArrayForReadWithNoCustomIteration>(a); } Cast<JSReceiver>(implicit context: Context)(o: HeapObject): JSReceiver @@ -1990,7 +2125,7 @@ extern macro ChangeInt32ToIntPtr(int32): intptr; // Sign-extends. extern macro ChangeUint32ToWord(uint32): uintptr; // Doesn't sign-extend. extern macro LoadNativeContext(Context): NativeContext; extern macro TruncateFloat64ToFloat32(float64): float32; -extern macro TruncateHeapNumberValueToWord32(Number): int32; +extern macro TruncateHeapNumberValueToWord32(HeapNumber): int32; extern macro LoadJSArrayElementsMap(constexpr ElementsKind, Context): Map; extern macro LoadJSArrayElementsMap(ElementsKind, Context): Map; extern macro ChangeNonnegativeNumberToUintPtr(Number): uintptr; @@ -2007,13 +2142,14 @@ extern macro Float64Constant(constexpr float64): float64; extern macro SmiConstant(constexpr int31): Smi; extern macro SmiConstant(constexpr Smi): Smi; extern macro SmiConstant(constexpr MessageTemplate): Smi; +extern macro SmiConstant(constexpr LanguageMode): Smi; extern macro BoolConstant(constexpr bool): bool; extern macro StringConstant(constexpr string): String; -extern macro LanguageModeConstant(constexpr LanguageMode): LanguageMode; extern macro Int32Constant(constexpr ElementsKind): ElementsKind; extern macro IntPtrConstant(constexpr NativeContextSlot): NativeContextSlot; extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot; extern macro IntPtrConstant(constexpr intptr): intptr; +extern macro PointerConstant(constexpr RawPtr): RawPtr; extern macro SingleCharacterStringConstant(constexpr string): String; extern macro BitcastWordToTaggedSigned(intptr): Smi; @@ -2126,6 +2262,9 @@ Convert<Number, int32>(i: int32): Number { Convert<intptr, int32>(i: int32): intptr { return ChangeInt32ToIntPtr(i); } +Convert<intptr, uint32>(i: uint32): intptr { + return Signed(ChangeUint32ToWord(i)); +} Convert<Smi, int32>(i: int32): Smi { return SmiFromInt32(i); } @@ -2333,10 +2472,6 @@ extern operator '.floats[]=' macro StoreFixedDoubleArrayElement( FixedDoubleArray, intptr, float64): void; extern operator '.floats[]=' macro StoreFixedDoubleArrayElementSmi( FixedDoubleArray, Smi, float64): void; -operator '.floats[]=' macro StoreFixedDoubleArrayElementSmi( - a: FixedDoubleArray, i: Smi, n: Number): void { - StoreFixedDoubleArrayElementSmi(a, i, Convert<float64>(n)); -} operator '[]=' macro StoreFixedDoubleArrayDirect( a: FixedDoubleArray, i: Smi, v: Number) { a.floats[i] = Convert<float64>(v); @@ -2418,7 +2553,7 @@ extern macro AllocateJSArray(constexpr ElementsKind, Map, Smi, Smi): JSArray; extern macro AllocateJSArray(Map, FixedArrayBase, Smi): JSArray; extern macro AllocateJSObjectFromMap(Map): JSObject; extern macro AllocateJSObjectFromMap( - Map, FixedArray, FixedArray, constexpr AllocationFlags, + Map, FixedArray | PropertyArray, FixedArray, constexpr AllocationFlags, constexpr SlackTrackingMode): JSObject; extern macro LoadDoubleWithHoleCheck(FixedDoubleArray, Smi): float64 @@ -2531,10 +2666,10 @@ LoadElementNoHole<FixedArray>(implicit context: Context)( a: JSArray, index: Smi): Object labels IfHole { try { - let elements: FixedArray = + const elements: FixedArray = Cast<FixedArray>(a.elements) otherwise Unexpected; - let e: Object = elements.objects[index]; - if (e == Hole) { + const e: Object = elements.objects[index]; + if (e == TheHole) { goto IfHole; } return e; @@ -2548,9 +2683,10 @@ LoadElementNoHole<FixedDoubleArray>(implicit context: Context)( a: JSArray, index: Smi): Object labels IfHole { try { - let elements: FixedDoubleArray = + const elements: FixedDoubleArray = Cast<FixedDoubleArray>(a.elements) otherwise Unexpected; - let e: float64 = LoadDoubleWithHoleCheck(elements, index) otherwise IfHole; + const e: float64 = + LoadDoubleWithHoleCheck(elements, index) otherwise IfHole; return AllocateHeapNumberWithValue(e); } label Unexpected { @@ -2594,7 +2730,7 @@ struct FastJSArrayWitness { } else { const elements = Cast<FixedArray>(this.unstable.elements) otherwise unreachable; - StoreFixedArrayElement(elements, k, Hole); + StoreFixedArrayElement(elements, k, TheHole); } } @@ -2638,12 +2774,12 @@ struct FastJSArrayWitness { MoveElements(dst: intptr, src: intptr, length: intptr) { assert(this.arrayIsPushable); if (this.hasDoubles) { - let elements: FixedDoubleArray = + const elements: FixedDoubleArray = Cast<FixedDoubleArray>(this.unstable.elements) otherwise unreachable; TorqueMoveElements(elements, dst, src, length); } else { - let elements: FixedArray = Cast<FixedArray>(this.unstable.elements) + const elements: FixedArray = Cast<FixedArray>(this.unstable.elements) otherwise unreachable; if (this.hasSmis) { TorqueMoveElementsSmi(elements, dst, src, length); @@ -2662,17 +2798,62 @@ struct FastJSArrayWitness { } macro NewFastJSArrayWitness(array: FastJSArray): FastJSArrayWitness { - let kind = array.map.elements_kind; + const kind = array.map.elements_kind; return FastJSArrayWitness{ stable: array, unstable: array, map: array.map, - hasDoubles: !IsElementsKindLessThanOrEqual(kind, HOLEY_ELEMENTS), + hasDoubles: IsDoubleElementsKind(kind), hasSmis: IsElementsKindLessThanOrEqual(kind, HOLEY_SMI_ELEMENTS), arrayIsPushable: false }; } +struct FastJSArrayForReadWitness { + Get(): FastJSArrayForRead { + return this.unstable; + } + + Recheck() labels CastError { + if (this.stable.map != this.map) goto CastError; + // We don't need to check elements kind or whether the prototype + // has changed away from the default JSArray prototype, because + // if the map remains the same then those properties hold. + // + // However, we have to make sure there are no elements in the + // prototype chain. + if (IsNoElementsProtectorCellInvalid()) goto CastError; + this.unstable = %RawDownCast<FastJSArrayForRead>(this.stable); + } + + LoadElementNoHole(implicit context: Context)(k: Smi): Object + labels FoundHole { + if (this.hasDoubles) { + return LoadElementNoHole<FixedDoubleArray>(this.unstable, k) + otherwise FoundHole; + } else { + return LoadElementNoHole<FixedArray>(this.unstable, k) + otherwise FoundHole; + } + } + + const stable: JSArray; + unstable: FastJSArrayForRead; + const map: Map; + const hasDoubles: bool; +} + +macro NewFastJSArrayForReadWitness(array: FastJSArrayForRead): + FastJSArrayForReadWitness { + const kind = array.map.elements_kind; + return FastJSArrayForReadWitness{ + stable: array, + unstable: array, + map: array.map, + hasDoubles: IsDoubleElementsKind(kind) + }; +} + extern macro TransitionElementsKind( JSObject, Map, constexpr ElementsKind, constexpr ElementsKind): void labels Bailout; @@ -2693,6 +2874,7 @@ extern macro IsJSReceiver(HeapObject): bool; extern macro TaggedIsCallable(Object): bool; extern macro IsDetachedBuffer(JSArrayBuffer): bool; extern macro IsHeapNumber(HeapObject): bool; +extern macro IsBigInt(HeapObject): bool; extern macro IsFixedArray(HeapObject): bool; extern macro IsName(HeapObject): bool; extern macro IsPrivateSymbol(HeapObject): bool; @@ -2702,7 +2884,7 @@ extern macro IsOddball(HeapObject): bool; extern macro IsSymbol(HeapObject): bool; extern macro IsJSArrayMap(Map): bool; extern macro IsExtensibleMap(Map): bool; -extern macro IsJSValue(HeapObject): bool; +extern macro IsJSPrimitiveWrapper(HeapObject): bool; extern macro IsCustomElementsReceiverInstanceType(int32): bool; extern macro Typeof(Object): Object; @@ -2713,7 +2895,7 @@ macro NumberIsNaN(number: Number): bool { return false; } case (hn: HeapNumber): { - let value: float64 = Convert<float64>(hn); + const value: float64 = Convert<float64>(hn); return value != value; } } @@ -2722,6 +2904,8 @@ macro NumberIsNaN(number: Number): bool { extern macro GotoIfForceSlowPath() labels Taken; extern macro BranchIfToBooleanIsTrue(Object): never labels Taken, NotTaken; +extern macro BranchIfToBooleanIsFalse(Object): never + labels Taken, NotTaken; macro ToBoolean(obj: Object): bool { if (BranchIfToBooleanIsTrue(obj)) { @@ -2731,13 +2915,24 @@ macro ToBoolean(obj: Object): bool { } } +@export +macro RequireObjectCoercible(implicit context: Context)( + value: Object, name: constexpr string): Object { + if (IsNullOrUndefined(value)) { + ThrowTypeError(kCalledOnNullOrUndefined, name); + } + return value; +} + +extern macro BranchIfSameValue(Object, Object): never labels Taken, NotTaken; + transitioning macro ToIndex(input: Object, context: Context): Number labels RangeError { if (input == Undefined) { return 0; } - let value: Number = ToInteger_Inline(context, input, kTruncateMinusZero); + const value: Number = ToInteger_Inline(context, input, kTruncateMinusZero); if (value < 0 || value > kMaxSafeInteger) { goto RangeError; } @@ -2824,19 +3019,6 @@ macro BranchIfFastJSArrayForRead(o: Object, context: Context): BranchIf<FastJSArrayForRead>(o) otherwise True, False; } -macro BranchIfNotFastJSArray(o: Object, context: Context): never - labels True, False { - BranchIfNot<FastJSArray>(o) otherwise True, False; -} - -macro BranchIfFastJSArrayForCopy(o: Object, context: Context): never - labels True, False { - // Long-term, it's likely not a good idea to have this slow-path test here, - // since it fundamentally breaks the type system. - GotoIfForceSlowPath() otherwise False; - BranchIf<FastJSArrayForCopy>(o) otherwise True, False; -} - @export macro IsFastJSArrayWithNoCustomIteration(context: Context, o: Object): bool { return Is<FastJSArrayWithNoCustomIteration>(o); @@ -2859,7 +3041,7 @@ namespace runtime { transitioning builtin FastCreateDataProperty(implicit context: Context)( receiver: JSReceiver, key: Object, value: Object): Object { try { - let array = Cast<FastJSArray>(receiver) otherwise Slow; + const array = Cast<FastJSArray>(receiver) otherwise Slow; const index: Smi = Cast<Smi>(key) otherwise goto Slow; if (index < 0 || index > array.length) goto Slow; array::EnsureWriteableFastElements(array); @@ -2929,3 +3111,46 @@ transitioning macro ToStringImpl(context: Context, o: Object): String { } unreachable; } + +macro VerifiedUnreachable(): never { + StaticAssert(false); + unreachable; +} + +macro Float64IsSomeInfinity(value: float64): bool { + if (value == V8_INFINITY) { + return true; + } + return value == (Convert<float64>(0) - V8_INFINITY); +} + +@export +macro IsIntegerOrSomeInfinity(o: Object): bool { + typeswitch (o) { + case (Smi): { + return true; + } + case (hn: HeapNumber): { + if (Float64IsSomeInfinity(Convert<float64>(hn))) { + return true; + } + return IsInteger(hn); + } + case (Object): { + return false; + } + } +} + +builtin CheckNumberInRange(implicit context: Context)( + value: Number, min: Number, max: Number): Undefined { + if (IsIntegerOrSomeInfinity(value) && min <= value && value <= max) { + return Undefined; + } else { + Print('Range type assertion failed! (value/min/max)'); + Print(value); + Print(min); + Print(max); + unreachable; + } +} diff --git a/deps/v8/src/builtins/bigint.tq b/deps/v8/src/builtins/bigint.tq new file mode 100644 index 0000000000..a1b1cb6780 --- /dev/null +++ b/deps/v8/src/builtins/bigint.tq @@ -0,0 +1,206 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-bigint-gen.h' + +// TODO(nicohartmann): Discuss whether types used by multiple builtins should be +// in global namespace +@noVerifier +extern class BigIntBase extends HeapObject generates 'TNode<BigInt>' { +} + +type BigInt extends BigIntBase; + +@noVerifier +@hasSameInstanceTypeAsParent +extern class MutableBigInt extends BigIntBase generates 'TNode<BigInt>' { +} + +Convert<BigInt, MutableBigInt>(i: MutableBigInt): BigInt { + assert(bigint::IsCanonicalized(i)); + return %RawDownCast<BigInt>(Convert<BigIntBase>(i)); +} + +namespace bigint { + + const kPositiveSign: uint32 = 0; + const kNegativeSign: uint32 = 1; + + extern macro BigIntBuiltinsAssembler::CppAbsoluteAddAndCanonicalize( + MutableBigInt, BigIntBase, BigIntBase): void; + extern macro BigIntBuiltinsAssembler::CppAbsoluteSubAndCanonicalize( + MutableBigInt, BigIntBase, BigIntBase): void; + extern macro BigIntBuiltinsAssembler::CppAbsoluteCompare( + BigIntBase, BigIntBase): int32; + + extern macro BigIntBuiltinsAssembler::ReadBigIntSign(BigIntBase): uint32; + extern macro BigIntBuiltinsAssembler::ReadBigIntLength(BigIntBase): intptr; + extern macro BigIntBuiltinsAssembler::WriteBigIntSignAndLength( + MutableBigInt, uint32, intptr): void; + + extern macro CodeStubAssembler::AllocateBigInt(intptr): MutableBigInt; + extern macro CodeStubAssembler::StoreBigIntDigit( + MutableBigInt, intptr, uintptr): void; + extern macro CodeStubAssembler::LoadBigIntDigit(BigIntBase, intptr): uintptr; + + @export // Silence unused warning. + // TODO(szuend): Remove @export once macros that are only used in + // asserts are no longer detected as unused. + macro IsCanonicalized(bigint: BigIntBase): bool { + const length = ReadBigIntLength(bigint); + + if (length == 0) { + return ReadBigIntSign(bigint) == kPositiveSign; + } + + return LoadBigIntDigit(bigint, length - 1) != 0; + } + + macro InvertSign(sign: uint32): uint32 { + return sign == kPositiveSign ? kNegativeSign : kPositiveSign; + } + + macro AllocateEmptyBigIntNoThrow(implicit context: Context)( + sign: uint32, length: intptr): MutableBigInt labels BigIntTooBig { + if (length > kBigIntMaxLength) { + goto BigIntTooBig; + } + const result: MutableBigInt = AllocateBigInt(length); + + WriteBigIntSignAndLength(result, sign, length); + return result; + } + + macro AllocateEmptyBigInt(implicit context: Context)( + sign: uint32, length: intptr): MutableBigInt { + try { + return AllocateEmptyBigIntNoThrow(sign, length) otherwise BigIntTooBig; + } + label BigIntTooBig { + ThrowRangeError(kBigIntTooBig); + } + } + + macro MutableBigIntAbsoluteCompare(x: BigIntBase, y: BigIntBase): int32 { + return CppAbsoluteCompare(x, y); + } + + macro MutableBigIntAbsoluteSub(implicit context: Context)( + x: BigInt, y: BigInt, resultSign: uint32): BigInt { + const xlength = ReadBigIntLength(x); + const ylength = ReadBigIntLength(y); + const xsign = ReadBigIntSign(x); + + assert(MutableBigIntAbsoluteCompare(x, y) >= 0); + if (xlength == 0) { + assert(ylength == 0); + return x; + } + + if (ylength == 0) { + return resultSign == xsign ? x : BigIntUnaryMinus(x); + } + + const result = AllocateEmptyBigInt(resultSign, xlength); + CppAbsoluteSubAndCanonicalize(result, x, y); + return Convert<BigInt>(result); + } + + macro MutableBigIntAbsoluteAdd(implicit context: Context)( + xBigint: BigInt, yBigint: BigInt, + resultSign: uint32): BigInt labels BigIntTooBig { + let xlength = ReadBigIntLength(xBigint); + let ylength = ReadBigIntLength(yBigint); + + let x = xBigint; + let y = yBigint; + if (xlength < ylength) { + // Swap x and y so that x is longer. + x = yBigint; + y = xBigint; + const tempLength = xlength; + xlength = ylength; + ylength = tempLength; + } + + // case: 0n + 0n + if (xlength == 0) { + assert(ylength == 0); + return x; + } + + // case: x + 0n + if (ylength == 0) { + return resultSign == ReadBigIntSign(x) ? x : BigIntUnaryMinus(x); + } + + // case: x + y + const result = AllocateEmptyBigIntNoThrow(resultSign, xlength + 1) + otherwise BigIntTooBig; + CppAbsoluteAddAndCanonicalize(result, x, y); + return Convert<BigInt>(result); + } + + macro BigIntAddImpl(implicit context: Context)(x: BigInt, y: BigInt): BigInt + labels BigIntTooBig { + const xsign = ReadBigIntSign(x); + const ysign = ReadBigIntSign(y); + if (xsign == ysign) { + // x + y == x + y + // -x + -y == -(x + y) + return MutableBigIntAbsoluteAdd(x, y, xsign) otherwise BigIntTooBig; + } + + // x + -y == x - y == -(y - x) + // -x + y == y - x == -(x - y) + if (MutableBigIntAbsoluteCompare(x, y) >= 0) { + return MutableBigIntAbsoluteSub(x, y, xsign); + } + return MutableBigIntAbsoluteSub(y, x, InvertSign(xsign)); + } + + builtin BigIntAddNoThrow(implicit context: Context)(x: BigInt, y: BigInt): + Numeric { + try { + return BigIntAddImpl(x, y) otherwise BigIntTooBig; + } + label BigIntTooBig { + // Smi sentinal is used to signal BigIntTooBig exception. + return Convert<Smi>(0); + } + } + + builtin BigIntAdd(implicit context: Context)(xNum: Numeric, yNum: Numeric): + BigInt { + try { + const x = Cast<BigInt>(xNum) otherwise MixedTypes; + const y = Cast<BigInt>(yNum) otherwise MixedTypes; + + return BigIntAddImpl(x, y) otherwise BigIntTooBig; + } + label MixedTypes { + ThrowTypeError(kBigIntMixedTypes); + } + label BigIntTooBig { + ThrowRangeError(kBigIntTooBig); + } + } + + builtin BigIntUnaryMinus(implicit context: Context)(bigint: BigInt): BigInt { + const length = ReadBigIntLength(bigint); + + // There is no -0n. + if (length == 0) { + return bigint; + } + + const result = + AllocateEmptyBigInt(InvertSign(ReadBigIntSign(bigint)), length); + for (let i: intptr = 0; i < length; ++i) { + StoreBigIntDigit(result, i, LoadBigIntDigit(bigint, i)); + } + return Convert<BigInt>(result); + } + +} // namespace bigint diff --git a/deps/v8/src/builtins/boolean.tq b/deps/v8/src/builtins/boolean.tq index a41ef76d21..25f9ebd396 100644 --- a/deps/v8/src/builtins/boolean.tq +++ b/deps/v8/src/builtins/boolean.tq @@ -3,39 +3,20 @@ // found in the LICENSE file. namespace boolean { - const kNameDictionaryInitialCapacity: - constexpr int32 generates 'NameDictionary::kInitialCapacity'; - - extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool; - extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32): - NameDictionary; - - // TODO(v8:9120): This is a workaround to get access to target and new.target - // in javascript builtins. Requires cleanup once this is fully supported by - // torque. - const NEW_TARGET_INDEX: - constexpr int32 generates 'Descriptor::kJSNewTarget'; - const TARGET_INDEX: constexpr int32 generates 'Descriptor::kJSTarget'; - extern macro Parameter(constexpr int32): Object; - javascript builtin - BooleanConstructor(context: Context, receiver: Object, ...arguments): Object { + BooleanConstructor( + js-implicit context: Context, receiver: Object, newTarget: Object, + target: JSFunction)(...arguments): Object { const value = SelectBooleanConstant(ToBoolean(arguments[0])); - const newTarget = Parameter(NEW_TARGET_INDEX); if (newTarget == Undefined) { return value; } - const target = UnsafeCast<JSFunction>(Parameter(TARGET_INDEX)); const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget)); - let properties = kEmptyFixedArray; - if (IsDictionaryMap(map)) { - properties = AllocateNameDictionary(kNameDictionaryInitialCapacity); - } - const obj = UnsafeCast<JSValue>(AllocateJSObjectFromMap( - map, properties, kEmptyFixedArray, kNone, kWithSlackTracking)); + const obj = + UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map)); obj.value = value; return obj; } diff --git a/deps/v8/src/builtins/builtins-api.cc b/deps/v8/src/builtins/builtins-api.cc index 7ee879ab51..0c30e52154 100644 --- a/deps/v8/src/builtins/builtins-api.cc +++ b/deps/v8/src/builtins/builtins-api.cc @@ -32,14 +32,16 @@ JSReceiver GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo info, JSObject js_obj_receiver = JSObject::cast(receiver); FunctionTemplateInfo signature = FunctionTemplateInfo::cast(recv_type); - // Check the receiver. Fast path for receivers with no hidden prototypes. + // Check the receiver. if (signature.IsTemplateFor(js_obj_receiver)) return receiver; - if (!js_obj_receiver.map().has_hidden_prototype()) return JSReceiver(); - for (PrototypeIterator iter(isolate, js_obj_receiver, kStartAtPrototype, - PrototypeIterator::END_AT_NON_HIDDEN); - !iter.IsAtEnd(); iter.Advance()) { - JSObject current = iter.GetCurrent<JSObject>(); - if (signature.IsTemplateFor(current)) return current; + + // The JSGlobalProxy might have a hidden prototype. + if (V8_UNLIKELY(js_obj_receiver.IsJSGlobalProxy())) { + HeapObject prototype = js_obj_receiver.map().prototype(); + if (!prototype.IsNull(isolate)) { + JSObject js_obj_prototype = JSObject::cast(prototype); + if (signature.IsTemplateFor(js_obj_prototype)) return js_obj_prototype; + } } return JSReceiver(); } diff --git a/deps/v8/src/builtins/builtins-arguments-gen.cc b/deps/v8/src/builtins/builtins-arguments-gen.cc index 6cc9fd9623..d65d57cc79 100644 --- a/deps/v8/src/builtins/builtins-arguments-gen.cc +++ b/deps/v8/src/builtins/builtins-arguments-gen.cc @@ -266,7 +266,8 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, var_list1, argument_offset, mapped_offset, [this, elements, ¤t_argument](Node* offset) { Increment(¤t_argument, kSystemPointerSize); - Node* arg = LoadBufferObject(current_argument.value(), 0); + Node* arg = LoadBufferObject( + UncheckedCast<RawPtrT>(current_argument.value()), 0); StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset, arg); }, diff --git a/deps/v8/src/builtins/builtins-array-gen.cc b/deps/v8/src/builtins/builtins-array-gen.cc index 29bcae6feb..07f74cb429 100644 --- a/deps/v8/src/builtins/builtins-array-gen.cc +++ b/deps/v8/src/builtins/builtins-array-gen.cc @@ -227,7 +227,7 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler( VariableList list({&a_, &k_, &to_}, zone()); FastLoopBody body = [&](Node* index) { - GotoIf(IsDetachedBuffer(array_buffer), detached); + GotoIf(IsDetachedBuffer(CAST(array_buffer)), detached); TNode<RawPtrT> data_ptr = LoadJSTypedArrayBackingStore(typed_array); Node* value = LoadFixedTypedArrayElementAsTagged( data_ptr, index, source_elements_kind_, SMI_PARAMETERS); @@ -402,7 +402,7 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) { CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); TNode<Object> receiver = args.GetReceiver(); TNode<JSArray> array_receiver; - Node* kind = nullptr; + TNode<Int32T> kind; Label fast(this); BranchIfFastJSArray(receiver, context, &fast, &runtime); @@ -709,19 +709,19 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) { iterator_assembler.GetIterator(context, items, iterator_method); TNode<Context> native_context = LoadNativeContext(context); - TNode<Object> fast_iterator_result_map = - LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX); + TNode<Map> fast_iterator_result_map = CAST( + LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX)); Goto(&loop); BIND(&loop); { // Loop while iterator is not done. - TNode<Object> next = iterator_assembler.IteratorStep( + TNode<JSReceiver> next = iterator_assembler.IteratorStep( context, iterator_record, &loop_done, fast_iterator_result_map); TVARIABLE(Object, value, - CAST(iterator_assembler.IteratorValue( - context, next, fast_iterator_result_map))); + iterator_assembler.IteratorValue(context, next, + fast_iterator_result_map)); // If a map_function is supplied then call it (using this_arg as // receiver), on the value returned from the iterator. Exceptions are @@ -2035,8 +2035,7 @@ void ArrayBuiltinsAssembler::CreateArrayDispatchSingleArgument( &normal_sequence); { // Make elements kind holey and update elements kind in the type info. - var_elements_kind = - Signed(Word32Or(var_elements_kind.value(), Int32Constant(1))); + var_elements_kind = Word32Or(var_elements_kind.value(), Int32Constant(1)); StoreObjectFieldNoWriteBarrier( allocation_site, AllocationSite::kTransitionInfoOrBoilerplateOffset, SmiOr(transition_info, SmiConstant(fast_elements_kind_holey_mask))); diff --git a/deps/v8/src/builtins/builtins-array.cc b/deps/v8/src/builtins/builtins-array.cc index e6ab965a7e..96c10ed0fd 100644 --- a/deps/v8/src/builtins/builtins-array.cc +++ b/deps/v8/src/builtins/builtins-array.cc @@ -970,8 +970,9 @@ void CollectElementIndices(Isolate* isolate, Handle<JSObject> object, } case FAST_STRING_WRAPPER_ELEMENTS: case SLOW_STRING_WRAPPER_ELEMENTS: { - DCHECK(object->IsJSValue()); - Handle<JSValue> js_value = Handle<JSValue>::cast(object); + DCHECK(object->IsJSPrimitiveWrapper()); + Handle<JSPrimitiveWrapper> js_value = + Handle<JSPrimitiveWrapper>::cast(object); DCHECK(js_value->value().IsString()); Handle<String> string(String::cast(js_value->value()), isolate); uint32_t length = static_cast<uint32_t>(string->length()); diff --git a/deps/v8/src/builtins/builtins-async-function-gen.cc b/deps/v8/src/builtins/builtins-async-function-gen.cc index 03df1aaaad..a95365e425 100644 --- a/deps/v8/src/builtins/builtins-async-function-gen.cc +++ b/deps/v8/src/builtins/builtins-async-function-gen.cc @@ -36,6 +36,21 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwaitResumeClosure( TNode<JSAsyncFunctionObject> async_function_object = CAST(LoadContextElement(context, Context::EXTENSION_INDEX)); + // Push the promise for the {async_function_object} back onto the catch + // prediction stack to handle exceptions thrown after resuming from the + // await properly. + Label if_instrumentation(this, Label::kDeferred), + if_instrumentation_done(this); + Branch(IsDebugActive(), &if_instrumentation, &if_instrumentation_done); + BIND(&if_instrumentation); + { + TNode<JSPromise> promise = LoadObjectField<JSPromise>( + async_function_object, JSAsyncFunctionObject::kPromiseOffset); + CallRuntime(Runtime::kDebugAsyncFunctionResumed, context, promise); + Goto(&if_instrumentation_done); + } + BIND(&if_instrumentation_done); + // Inline version of GeneratorPrototypeNext / GeneratorPrototypeReturn with // unnecessary runtime checks removed. @@ -80,27 +95,19 @@ TF_BUILTIN(AsyncFunctionEnter, AsyncFunctionBuiltinsAssembler) { Signed(IntPtrAdd(WordSar(frame_size, IntPtrConstant(kTaggedSizeLog2)), formal_parameter_count)); - // Allocate space for the promise, the async function object - // and the register file. - TNode<IntPtrT> size = IntPtrAdd( - IntPtrConstant(JSPromise::kSizeWithEmbedderFields + - JSAsyncFunctionObject::kSize + FixedArray::kHeaderSize), - Signed(WordShl(parameters_and_register_length, - IntPtrConstant(kTaggedSizeLog2)))); - TNode<HeapObject> base = AllocateInNewSpace(size); - - // Initialize the register file. - TNode<FixedArray> parameters_and_registers = UncheckedCast<FixedArray>( - InnerAllocate(base, JSAsyncFunctionObject::kSize + - JSPromise::kSizeWithEmbedderFields)); - StoreMapNoWriteBarrier(parameters_and_registers, RootIndex::kFixedArrayMap); - StoreObjectFieldNoWriteBarrier(parameters_and_registers, - FixedArray::kLengthOffset, - SmiFromIntPtr(parameters_and_register_length)); + // Allocate and initialize the register file. + TNode<FixedArrayBase> parameters_and_registers = + AllocateFixedArray(HOLEY_ELEMENTS, parameters_and_register_length, + INTPTR_PARAMETERS, kAllowLargeObjectAllocation); FillFixedArrayWithValue(HOLEY_ELEMENTS, parameters_and_registers, IntPtrConstant(0), parameters_and_register_length, RootIndex::kUndefinedValue); + // Allocate space for the promise, the async function object. + TNode<IntPtrT> size = IntPtrConstant(JSPromise::kSizeWithEmbedderFields + + JSAsyncFunctionObject::kSize); + TNode<HeapObject> base = AllocateInNewSpace(size); + // Initialize the promise. TNode<Context> native_context = LoadNativeContext(context); TNode<JSFunction> promise_function = diff --git a/deps/v8/src/builtins/builtins-bigint-gen.cc b/deps/v8/src/builtins/builtins-bigint-gen.cc index 8a752f2517..d4818f0e01 100644 --- a/deps/v8/src/builtins/builtins-bigint-gen.cc +++ b/deps/v8/src/builtins/builtins-bigint-gen.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "src/builtins/builtins-bigint-gen.h" #include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins.h" #include "src/codegen/code-stub-assembler.h" diff --git a/deps/v8/src/builtins/builtins-bigint-gen.h b/deps/v8/src/builtins/builtins-bigint-gen.h new file mode 100644 index 0000000000..288418258b --- /dev/null +++ b/deps/v8/src/builtins/builtins-bigint-gen.h @@ -0,0 +1,80 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BUILTINS_BUILTINS_BIGINT_GEN_H_ +#define V8_BUILTINS_BUILTINS_BIGINT_GEN_H_ + +#include "src/codegen/code-stub-assembler.h" +#include "src/objects/bigint.h" + +namespace v8 { +namespace internal { + +class BigIntBuiltinsAssembler : public CodeStubAssembler { + public: + explicit BigIntBuiltinsAssembler(compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} + + TNode<IntPtrT> ReadBigIntLength(TNode<BigInt> value) { + TNode<Word32T> bitfield = LoadBigIntBitfield(value); + return ChangeInt32ToIntPtr( + Signed(DecodeWord32<BigIntBase::LengthBits>(bitfield))); + } + + TNode<Uint32T> ReadBigIntSign(TNode<BigInt> value) { + TNode<Word32T> bitfield = LoadBigIntBitfield(value); + return DecodeWord32<BigIntBase::SignBits>(bitfield); + } + + void WriteBigIntSignAndLength(TNode<BigInt> bigint, TNode<Uint32T> sign, + TNode<IntPtrT> length) { + STATIC_ASSERT(BigIntBase::SignBits::kShift == 0); + TNode<Uint32T> bitfield = Unsigned( + Word32Or(Word32Shl(TruncateIntPtrToInt32(length), + Int32Constant(BigIntBase::LengthBits::kShift)), + Word32And(sign, Int32Constant(BigIntBase::SignBits::kMask)))); + StoreBigIntBitfield(bigint, bitfield); + } + + void CppAbsoluteAddAndCanonicalize(TNode<BigInt> result, TNode<BigInt> x, + TNode<BigInt> y) { + TNode<ExternalReference> mutable_big_int_absolute_add_and_canonicalize = + ExternalConstant( + ExternalReference:: + mutable_big_int_absolute_add_and_canonicalize_function()); + CallCFunction(mutable_big_int_absolute_add_and_canonicalize, + MachineType::AnyTagged(), + std::make_pair(MachineType::AnyTagged(), result), + std::make_pair(MachineType::AnyTagged(), x), + std::make_pair(MachineType::AnyTagged(), y)); + } + + void CppAbsoluteSubAndCanonicalize(TNode<BigInt> result, TNode<BigInt> x, + TNode<BigInt> y) { + TNode<ExternalReference> mutable_big_int_absolute_sub_and_canonicalize = + ExternalConstant( + ExternalReference:: + mutable_big_int_absolute_sub_and_canonicalize_function()); + CallCFunction(mutable_big_int_absolute_sub_and_canonicalize, + MachineType::AnyTagged(), + std::make_pair(MachineType::AnyTagged(), result), + std::make_pair(MachineType::AnyTagged(), x), + std::make_pair(MachineType::AnyTagged(), y)); + } + + TNode<Int32T> CppAbsoluteCompare(TNode<BigInt> x, TNode<BigInt> y) { + TNode<ExternalReference> mutable_big_int_absolute_compare = + ExternalConstant( + ExternalReference::mutable_big_int_absolute_compare_function()); + TNode<Int32T> result = UncheckedCast<Int32T>( + CallCFunction(mutable_big_int_absolute_compare, MachineType::Int32(), + std::make_pair(MachineType::AnyTagged(), x), + std::make_pair(MachineType::AnyTagged(), y))); + return result; + } +}; + +} // namespace internal +} // namespace v8 +#endif // V8_BUILTINS_BUILTINS_BIGINT_GEN_H_ diff --git a/deps/v8/src/builtins/builtins-bigint.cc b/deps/v8/src/builtins/builtins-bigint.cc index a8a847ef47..09d71a0562 100644 --- a/deps/v8/src/builtins/builtins-bigint.cc +++ b/deps/v8/src/builtins/builtins-bigint.cc @@ -80,10 +80,10 @@ MaybeHandle<BigInt> ThisBigIntValue(Isolate* isolate, Handle<Object> value, // 1. If Type(value) is BigInt, return value. if (value->IsBigInt()) return Handle<BigInt>::cast(value); // 2. If Type(value) is Object and value has a [[BigIntData]] internal slot: - if (value->IsJSValue()) { + if (value->IsJSPrimitiveWrapper()) { // 2a. Assert: value.[[BigIntData]] is a BigInt value. // 2b. Return value.[[BigIntData]]. - Object data = JSValue::cast(*value).value(); + Object data = JSPrimitiveWrapper::cast(*value).value(); if (data.IsBigInt()) return handle(BigInt::cast(data), isolate); } // 3. Throw a TypeError exception. diff --git a/deps/v8/src/builtins/builtins-boolean-gen.cc b/deps/v8/src/builtins/builtins-boolean-gen.cc index 30cf7ba0c1..74474a8918 100644 --- a/deps/v8/src/builtins/builtins-boolean-gen.cc +++ b/deps/v8/src/builtins/builtins-boolean-gen.cc @@ -15,22 +15,23 @@ namespace internal { // ES6 #sec-boolean.prototype.tostring TF_BUILTIN(BooleanPrototypeToString, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); - Node* value = ToThisValue(context, receiver, PrimitiveType::kBoolean, - "Boolean.prototype.toString"); - Node* result = LoadObjectField(value, Oddball::kToStringOffset); + TNode<Oddball> value = + CAST(ToThisValue(context, receiver, PrimitiveType::kBoolean, + "Boolean.prototype.toString")); + TNode<String> result = CAST(LoadObjectField(value, Oddball::kToStringOffset)); Return(result); } // ES6 #sec-boolean.prototype.valueof TF_BUILTIN(BooleanPrototypeValueOf, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); - Node* result = ToThisValue(context, receiver, PrimitiveType::kBoolean, - "Boolean.prototype.valueOf"); + TNode<Oddball> result = CAST(ToThisValue( + context, receiver, PrimitiveType::kBoolean, "Boolean.prototype.valueOf")); Return(result); } diff --git a/deps/v8/src/builtins/builtins-call-gen.cc b/deps/v8/src/builtins/builtins-call-gen.cc index 05142a8f07..deb91dee24 100644 --- a/deps/v8/src/builtins/builtins-call-gen.cc +++ b/deps/v8/src/builtins/builtins-call-gen.cc @@ -475,14 +475,13 @@ TNode<JSReceiver> CallOrConstructBuiltinsAssembler::GetCompatibleReceiver( BIND(&holder_next); { - // Continue with the hidden prototype of the {holder} if it - // has one, or throw an illegal invocation exception, since - // the receiver did not pass the {signature} check. + // Continue with the hidden prototype of the {holder} if it is a + // JSGlobalProxy (the hidden prototype can either be null or a + // JSObject in that case), or throw an illegal invocation exception, + // since the receiver did not pass the {signature} check. TNode<Map> holder_map = LoadMap(holder); var_holder = LoadMapPrototype(holder_map); - GotoIf(IsSetWord32(LoadMapBitField2(holder_map), - Map::HasHiddenPrototypeBit::kMask), - &holder_loop); + GotoIf(IsJSGlobalProxyMap(holder_map), &holder_loop); ThrowTypeError(context, MessageTemplate::kIllegalInvocation); } } diff --git a/deps/v8/src/builtins/builtins-callsite.cc b/deps/v8/src/builtins/builtins-callsite.cc index d98eba4eeb..d1082291ef 100644 --- a/deps/v8/src/builtins/builtins-callsite.cc +++ b/deps/v8/src/builtins/builtins-callsite.cc @@ -8,6 +8,7 @@ #include "src/logging/counters.h" #include "src/objects/frame-array-inl.h" #include "src/objects/objects-inl.h" +#include "src/objects/stack-frame-info.h" namespace v8 { namespace internal { @@ -76,6 +77,9 @@ BUILTIN(CallSitePrototypeGetFunction) { StackFrameBase* frame = it.Frame(); if (frame->IsStrict()) return ReadOnlyRoots(isolate).undefined_value(); + + isolate->CountUsage(v8::Isolate::kCallSiteAPIGetFunctionSloppyCall); + return *frame->GetFunction(); } @@ -135,6 +139,9 @@ BUILTIN(CallSitePrototypeGetThis) { StackFrameBase* frame = it.Frame(); if (frame->IsStrict()) return ReadOnlyRoots(isolate).undefined_value(); + + isolate->CountUsage(v8::Isolate::kCallSiteAPIGetThisSloppyCall); + return *frame->GetReceiver(); } @@ -197,9 +204,9 @@ BUILTIN(CallSitePrototypeIsToplevel) { BUILTIN(CallSitePrototypeToString) { HandleScope scope(isolate); CHECK_CALLSITE(recv, "toString"); - FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), - GetFrameIndex(isolate, recv)); - RETURN_RESULT_OR_FAILURE(isolate, it.Frame()->ToString()); + Handle<StackTraceFrame> frame = isolate->factory()->NewStackTraceFrame( + GetFrameArray(isolate, recv), GetFrameIndex(isolate, recv)); + RETURN_RESULT_OR_FAILURE(isolate, SerializeStackTraceFrame(isolate, frame)); } #undef CHECK_CALLSITE diff --git a/deps/v8/src/builtins/builtins-collections-gen.cc b/deps/v8/src/builtins/builtins-collections-gen.cc index b5a9851c70..613e5f10ff 100644 --- a/deps/v8/src/builtins/builtins-collections-gen.cc +++ b/deps/v8/src/builtins/builtins-collections-gen.cc @@ -66,19 +66,19 @@ class BaseCollectionsAssembler : public CodeStubAssembler { TNode<Object> iterable); // Constructs a collection instance. Choosing a fast path when possible. - TNode<Object> AllocateJSCollection(TNode<Context> context, - TNode<JSFunction> constructor, - TNode<Object> new_target); + TNode<JSObject> AllocateJSCollection(TNode<Context> context, + TNode<JSFunction> constructor, + TNode<JSReceiver> new_target); // Fast path for constructing a collection instance if the constructor // function has not been modified. - TNode<Object> AllocateJSCollectionFast(TNode<HeapObject> constructor); + TNode<JSObject> AllocateJSCollectionFast(TNode<JSFunction> constructor); // Fallback for constructing a collection instance if the constructor function // has been modified. - TNode<Object> AllocateJSCollectionSlow(TNode<Context> context, - TNode<JSFunction> constructor, - TNode<Object> new_target); + TNode<JSObject> AllocateJSCollectionSlow(TNode<Context> context, + TNode<JSFunction> constructor, + TNode<JSReceiver> new_target); // Allocates the backing store for a collection. virtual TNode<Object> AllocateTable(Variant variant, TNode<Context> context, @@ -320,17 +320,17 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromIterable( CSA_ASSERT(this, Word32BinaryNot(IsUndefined(iterator.object))); - TNode<Object> fast_iterator_result_map = - LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX); + TNode<Map> fast_iterator_result_map = CAST( + LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX)); TVARIABLE(Object, var_exception); Goto(&loop); BIND(&loop); { - TNode<Object> next = iterator_assembler.IteratorStep( + TNode<JSReceiver> next = iterator_assembler.IteratorStep( context, iterator, &exit, fast_iterator_result_map); - TNode<Object> next_value = CAST(iterator_assembler.IteratorValue( - context, next, fast_iterator_result_map)); + TNode<Object> next_value = iterator_assembler.IteratorValue( + context, next, fast_iterator_result_map); AddConstructorEntry(variant, context, collection, add_func, next_value, nullptr, &if_exception, &var_exception); Goto(&loop); @@ -367,33 +367,33 @@ void BaseCollectionsAssembler::GotoIfInitialAddFunctionModified( GetAddFunctionNameIndex(variant), if_modified); } -TNode<Object> BaseCollectionsAssembler::AllocateJSCollection( +TNode<JSObject> BaseCollectionsAssembler::AllocateJSCollection( TNode<Context> context, TNode<JSFunction> constructor, - TNode<Object> new_target) { + TNode<JSReceiver> new_target) { TNode<BoolT> is_target_unmodified = WordEqual(constructor, new_target); - return Select<Object>(is_target_unmodified, - [=] { return AllocateJSCollectionFast(constructor); }, - [=] { - return AllocateJSCollectionSlow(context, constructor, - new_target); - }); + return Select<JSObject>( + is_target_unmodified, + [=] { return AllocateJSCollectionFast(constructor); }, + [=] { + return AllocateJSCollectionSlow(context, constructor, new_target); + }); } -TNode<Object> BaseCollectionsAssembler::AllocateJSCollectionFast( - TNode<HeapObject> constructor) { +TNode<JSObject> BaseCollectionsAssembler::AllocateJSCollectionFast( + TNode<JSFunction> constructor) { CSA_ASSERT(this, IsConstructorMap(LoadMap(constructor))); - TNode<Object> initial_map = - LoadObjectField(constructor, JSFunction::kPrototypeOrInitialMapOffset); - return CAST(AllocateJSObjectFromMap(initial_map)); + TNode<Map> initial_map = + CAST(LoadJSFunctionPrototypeOrInitialMap(constructor)); + return AllocateJSObjectFromMap(initial_map); } -TNode<Object> BaseCollectionsAssembler::AllocateJSCollectionSlow( +TNode<JSObject> BaseCollectionsAssembler::AllocateJSCollectionSlow( TNode<Context> context, TNode<JSFunction> constructor, - TNode<Object> new_target) { + TNode<JSReceiver> new_target) { ConstructorBuiltinsAssembler constructor_assembler(this->state()); - return CAST(constructor_assembler.EmitFastNewObject(context, constructor, - new_target)); + return constructor_assembler.EmitFastNewObject(context, constructor, + new_target); } void BaseCollectionsAssembler::GenerateConstructor( @@ -408,7 +408,7 @@ void BaseCollectionsAssembler::GenerateConstructor( TNode<Context> native_context = LoadNativeContext(context); TNode<Object> collection = AllocateJSCollection( - context, GetConstructor(variant, native_context), new_target); + context, GetConstructor(variant, native_context), CAST(new_target)); AddConstructorEntries(variant, context, native_context, collection, iterable); Return(collection); diff --git a/deps/v8/src/builtins/builtins-console.cc b/deps/v8/src/builtins/builtins-console.cc index 973f1785d1..9ab3566cec 100644 --- a/deps/v8/src/builtins/builtins-console.cc +++ b/deps/v8/src/builtins/builtins-console.cc @@ -39,7 +39,8 @@ namespace internal { namespace { void ConsoleCall( - Isolate* isolate, internal::BuiltinArguments& args, + Isolate* isolate, + internal::BuiltinArguments& args, // NOLINT(runtime/references) void (debug::ConsoleDelegate::*func)(const v8::debug::ConsoleCallArguments&, const v8::debug::ConsoleContext&)) { CHECK(!isolate->has_pending_exception()); diff --git a/deps/v8/src/builtins/builtins-constructor-gen.cc b/deps/v8/src/builtins/builtins-constructor-gen.cc index a725f3c4a1..767e626432 100644 --- a/deps/v8/src/builtins/builtins-constructor-gen.cc +++ b/deps/v8/src/builtins/builtins-constructor-gen.cc @@ -147,44 +147,40 @@ TF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) { } TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* target = Parameter(Descriptor::kTarget); - Node* new_target = Parameter(Descriptor::kNewTarget); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<JSFunction> target = CAST(Parameter(Descriptor::kTarget)); + TNode<JSReceiver> new_target = CAST(Parameter(Descriptor::kNewTarget)); Label call_runtime(this); - Node* result = EmitFastNewObject(context, target, new_target, &call_runtime); + TNode<JSObject> result = + EmitFastNewObject(context, target, new_target, &call_runtime); Return(result); BIND(&call_runtime); TailCallRuntime(Runtime::kNewObject, context, target, new_target); } -Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context, - Node* target, - Node* new_target) { - VARIABLE(var_obj, MachineRepresentation::kTagged); +compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( + SloppyTNode<Context> context, SloppyTNode<JSFunction> target, + SloppyTNode<JSReceiver> new_target) { + TVARIABLE(JSObject, var_obj); Label call_runtime(this), end(this); - Node* result = EmitFastNewObject(context, target, new_target, &call_runtime); - var_obj.Bind(result); + var_obj = EmitFastNewObject(context, target, new_target, &call_runtime); Goto(&end); BIND(&call_runtime); - var_obj.Bind(CallRuntime(Runtime::kNewObject, context, target, new_target)); + var_obj = CAST(CallRuntime(Runtime::kNewObject, context, target, new_target)); Goto(&end); BIND(&end); return var_obj.value(); } -Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context, - Node* target, - Node* new_target, - Label* call_runtime) { - CSA_ASSERT(this, HasInstanceType(target, JS_FUNCTION_TYPE)); - CSA_ASSERT(this, IsJSReceiver(new_target)); - +compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( + SloppyTNode<Context> context, SloppyTNode<JSFunction> target, + SloppyTNode<JSReceiver> new_target, Label* call_runtime) { // Verify that the new target is a JSFunction. Label fast(this), end(this); GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast); @@ -732,7 +728,7 @@ TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) { TNode<JSFunction> target = LoadTargetFromFrame(); Node* result = CallBuiltin(Builtins::kFastNewObject, context, target, new_target); - StoreObjectField(result, JSValue::kValueOffset, n_value); + StoreObjectField(result, JSPrimitiveWrapper::kValueOffset, n_value); args.PopAndReturn(result); } } @@ -798,7 +794,7 @@ TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) { Node* result = CallBuiltin(Builtins::kFastNewObject, context, target, new_target); - StoreObjectField(result, JSValue::kValueOffset, s_value); + StoreObjectField(result, JSPrimitiveWrapper::kValueOffset, s_value); args.PopAndReturn(result); } } diff --git a/deps/v8/src/builtins/builtins-constructor-gen.h b/deps/v8/src/builtins/builtins-constructor-gen.h index 9093a5a77b..9208506c79 100644 --- a/deps/v8/src/builtins/builtins-constructor-gen.h +++ b/deps/v8/src/builtins/builtins-constructor-gen.h @@ -31,10 +31,14 @@ class ConstructorBuiltinsAssembler : public CodeStubAssembler { Label* call_runtime); Node* EmitCreateEmptyObjectLiteral(Node* context); - Node* EmitFastNewObject(Node* context, Node* target, Node* new_target); - - Node* EmitFastNewObject(Node* context, Node* target, Node* new_target, - Label* call_runtime); + TNode<JSObject> EmitFastNewObject(SloppyTNode<Context> context, + SloppyTNode<JSFunction> target, + SloppyTNode<JSReceiver> new_target); + + TNode<JSObject> EmitFastNewObject(SloppyTNode<Context> context, + SloppyTNode<JSFunction> target, + SloppyTNode<JSReceiver> new_target, + Label* call_runtime); }; } // namespace internal diff --git a/deps/v8/src/builtins/builtins-conversion-gen.cc b/deps/v8/src/builtins/builtins-conversion-gen.cc index bc7e349ce1..71a9cbf145 100644 --- a/deps/v8/src/builtins/builtins-conversion-gen.cc +++ b/deps/v8/src/builtins/builtins-conversion-gen.cc @@ -392,7 +392,8 @@ TF_BUILTIN(ToInteger_TruncateMinusZero, CodeStubAssembler) { // ES6 section 7.1.13 ToObject (argument) TF_BUILTIN(ToObject, CodeStubAssembler) { Label if_smi(this, Label::kDeferred), if_jsreceiver(this), - if_noconstructor(this, Label::kDeferred), if_wrapjsvalue(this); + if_noconstructor(this, Label::kDeferred), + if_wrapjs_primitive_wrapper(this); Node* context = Parameter(Descriptor::kContext); Node* object = Parameter(Descriptor::kArgument); @@ -411,27 +412,30 @@ TF_BUILTIN(ToObject, CodeStubAssembler) { IntPtrConstant(Map::kNoConstructorFunctionIndex)), &if_noconstructor); constructor_function_index_var.Bind(constructor_function_index); - Goto(&if_wrapjsvalue); + Goto(&if_wrapjs_primitive_wrapper); BIND(&if_smi); constructor_function_index_var.Bind( IntPtrConstant(Context::NUMBER_FUNCTION_INDEX)); - Goto(&if_wrapjsvalue); + Goto(&if_wrapjs_primitive_wrapper); - BIND(&if_wrapjsvalue); + BIND(&if_wrapjs_primitive_wrapper); TNode<Context> native_context = LoadNativeContext(context); Node* constructor = LoadContextElement( native_context, constructor_function_index_var.value()); Node* initial_map = LoadObjectField(constructor, JSFunction::kPrototypeOrInitialMapOffset); - Node* js_value = Allocate(JSValue::kSize); - StoreMapNoWriteBarrier(js_value, initial_map); - StoreObjectFieldRoot(js_value, JSValue::kPropertiesOrHashOffset, + Node* js_primitive_wrapper = Allocate(JSPrimitiveWrapper::kSize); + StoreMapNoWriteBarrier(js_primitive_wrapper, initial_map); + StoreObjectFieldRoot(js_primitive_wrapper, + JSPrimitiveWrapper::kPropertiesOrHashOffset, RootIndex::kEmptyFixedArray); - StoreObjectFieldRoot(js_value, JSObject::kElementsOffset, + StoreObjectFieldRoot(js_primitive_wrapper, + JSPrimitiveWrapper::kElementsOffset, RootIndex::kEmptyFixedArray); - StoreObjectField(js_value, JSValue::kValueOffset, object); - Return(js_value); + StoreObjectField(js_primitive_wrapper, JSPrimitiveWrapper::kValueOffset, + object); + Return(js_primitive_wrapper); BIND(&if_noconstructor); ThrowTypeError(context, MessageTemplate::kUndefinedOrNullToObject, diff --git a/deps/v8/src/builtins/builtins-data-view-gen.h b/deps/v8/src/builtins/builtins-data-view-gen.h index eeb84f34db..d5c6571880 100644 --- a/deps/v8/src/builtins/builtins-data-view-gen.h +++ b/deps/v8/src/builtins/builtins-data-view-gen.h @@ -17,13 +17,13 @@ class DataViewBuiltinsAssembler : public CodeStubAssembler { explicit DataViewBuiltinsAssembler(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) {} - TNode<Int32T> LoadUint8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) { - return UncheckedCast<Int32T>( + TNode<Uint8T> LoadUint8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) { + return UncheckedCast<Uint8T>( Load(MachineType::Uint8(), data_pointer, offset)); } - TNode<Int32T> LoadInt8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) { - return UncheckedCast<Int32T>( + TNode<Int8T> LoadInt8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) { + return UncheckedCast<Int8T>( Load(MachineType::Int8(), data_pointer, offset)); } diff --git a/deps/v8/src/builtins/builtins-definitions.h b/deps/v8/src/builtins/builtins-definitions.h index 3412edb89d..23ab4a88ca 100644 --- a/deps/v8/src/builtins/builtins-definitions.h +++ b/deps/v8/src/builtins/builtins-definitions.h @@ -103,8 +103,8 @@ namespace internal { \ /* String helpers */ \ TFC(StringCharAt, StringAt) \ - TFC(StringCodePointAtUTF16, StringAt) \ - TFC(StringCodePointAtUTF32, StringAt) \ + TFC(StringCodePointAt, StringAt) \ + TFC(StringFromCodePointAt, StringAtAsString) \ TFC(StringEqual, Compare) \ TFC(StringGreaterThan, Compare) \ TFC(StringGreaterThanOrEqual, Compare) \ @@ -170,7 +170,9 @@ namespace internal { \ /* Adapters for Turbofan into runtime */ \ TFC(AllocateInYoungGeneration, Allocate) \ + TFC(AllocateRegularInYoungGeneration, Allocate) \ TFC(AllocateInOldGeneration, Allocate) \ + TFC(AllocateRegularInOldGeneration, Allocate) \ \ /* TurboFan support builtins */ \ TFS(CopyFastSmiOrObjectElements, kObject) \ @@ -266,7 +268,7 @@ namespace internal { \ /* Abort */ \ TFC(Abort, Abort) \ - TFC(AbortJS, Abort) \ + TFC(AbortCSAAssert, Abort) \ \ /* Built-in functions for Javascript */ \ /* Special internal builtins */ \ @@ -726,16 +728,12 @@ namespace internal { CPP(ObjectGetOwnPropertyDescriptors) \ TFJ(ObjectGetOwnPropertyNames, 1, kReceiver, kObject) \ CPP(ObjectGetOwnPropertySymbols) \ - CPP(ObjectGetPrototypeOf) \ - CPP(ObjectSetPrototypeOf) \ TFJ(ObjectIs, 2, kReceiver, kLeft, kRight) \ - CPP(ObjectIsExtensible) \ CPP(ObjectIsFrozen) \ CPP(ObjectIsSealed) \ TFJ(ObjectKeys, 1, kReceiver, kObject) \ CPP(ObjectLookupGetter) \ CPP(ObjectLookupSetter) \ - CPP(ObjectPreventExtensions) \ /* ES6 #sec-object.prototype.tostring */ \ TFJ(ObjectPrototypeToString, 0, kReceiver) \ /* ES6 #sec-object.prototype.valueof */ \ @@ -823,16 +821,10 @@ namespace internal { ASM(ReflectApply, Dummy) \ ASM(ReflectConstruct, Dummy) \ CPP(ReflectDefineProperty) \ - CPP(ReflectDeleteProperty) \ - CPP(ReflectGet) \ CPP(ReflectGetOwnPropertyDescriptor) \ - CPP(ReflectGetPrototypeOf) \ TFJ(ReflectHas, 2, kReceiver, kTarget, kKey) \ - CPP(ReflectIsExtensible) \ CPP(ReflectOwnKeys) \ - CPP(ReflectPreventExtensions) \ CPP(ReflectSet) \ - CPP(ReflectSetPrototypeOf) \ \ /* RegExp */ \ CPP(RegExpCapture1Getter) \ @@ -1150,6 +1142,7 @@ namespace internal { ASM(StackCheck, Dummy) \ ASM(DoubleToI, Dummy) \ TFC(GetProperty, GetProperty) \ + TFS(GetPropertyWithReceiver, kObject, kKey, kReceiver, kOnNonExistent) \ TFS(SetProperty, kReceiver, kKey, kValue) \ TFS(SetPropertyInLiteral, kReceiver, kKey, kValue) \ ASM(MemCopyUint8Uint8, CCall) \ diff --git a/deps/v8/src/builtins/builtins-error.cc b/deps/v8/src/builtins/builtins-error.cc index e099baeb34..3bcc7356d4 100644 --- a/deps/v8/src/builtins/builtins-error.cc +++ b/deps/v8/src/builtins/builtins-error.cc @@ -31,10 +31,11 @@ BUILTIN(ErrorConstructor) { } RETURN_RESULT_OR_FAILURE( - isolate, ErrorUtils::Construct(isolate, args.target(), - Handle<Object>::cast(args.new_target()), - args.atOrUndefined(isolate, 1), mode, - caller, false)); + isolate, + ErrorUtils::Construct(isolate, args.target(), + Handle<Object>::cast(args.new_target()), + args.atOrUndefined(isolate, 1), mode, caller, + ErrorUtils::StackTraceCollection::kDetailed)); } // static diff --git a/deps/v8/src/builtins/builtins-global.cc b/deps/v8/src/builtins/builtins-global.cc index 53e974c452..137f7f3402 100644 --- a/deps/v8/src/builtins/builtins-global.cc +++ b/deps/v8/src/builtins/builtins-global.cc @@ -86,17 +86,27 @@ BUILTIN(GlobalEval) { Handle<Object> x = args.atOrUndefined(isolate, 1); Handle<JSFunction> target = args.target(); Handle<JSObject> target_global_proxy(target->global_proxy(), isolate); - if (!x->IsString()) return *x; if (!Builtins::AllowDynamicFunction(isolate, target, target_global_proxy)) { isolate->CountUsage(v8::Isolate::kFunctionConstructorReturnedUndefined); return ReadOnlyRoots(isolate).undefined_value(); } + + // Run embedder pre-checks before executing eval. If the argument is a + // non-String (or other object the embedder doesn't know to handle), then + // return it directly. + MaybeHandle<String> source; + bool unhandled_object; + std::tie(source, unhandled_object) = + Compiler::ValidateDynamicCompilationSource( + isolate, handle(target->native_context(), isolate), x); + if (unhandled_object) return *x; + Handle<JSFunction> function; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, function, - Compiler::GetFunctionFromString(handle(target->native_context(), isolate), - Handle<String>::cast(x), - NO_PARSE_RESTRICTION, kNoSourcePosition)); + Compiler::GetFunctionFromValidatedString( + handle(target->native_context(), isolate), source, + NO_PARSE_RESTRICTION, kNoSourcePosition)); RETURN_RESULT_OR_FAILURE( isolate, Execution::Call(isolate, function, target_global_proxy, 0, nullptr)); diff --git a/deps/v8/src/builtins/builtins-handler-gen.cc b/deps/v8/src/builtins/builtins-handler-gen.cc index d1b50f2cdc..973356f569 100644 --- a/deps/v8/src/builtins/builtins-handler-gen.cc +++ b/deps/v8/src/builtins/builtins-handler-gen.cc @@ -28,7 +28,8 @@ class HandlerBuiltinsAssembler : public CodeStubAssembler { // kind. Use with caution. This produces a *lot* of code. using ElementsKindSwitchCase = std::function<void(ElementsKind)>; void DispatchByElementsKind(TNode<Int32T> elements_kind, - const ElementsKindSwitchCase& case_function); + const ElementsKindSwitchCase& case_function, + bool handle_typed_elements_kind); // Dispatches over all possible combinations of {from,to} elements kinds. using ElementsKindTransitionSwitchCase = @@ -48,7 +49,7 @@ TF_BUILTIN(LoadIC_StringLength, CodeStubAssembler) { TF_BUILTIN(LoadIC_StringWrapperLength, CodeStubAssembler) { Node* value = Parameter(Descriptor::kReceiver); - Node* string = LoadJSValueValue(value); + Node* string = LoadJSPrimitiveWrapperValue(value); Return(LoadStringLengthAsSmi(string)); } @@ -227,7 +228,7 @@ void HandlerBuiltinsAssembler::Generate_ElementsTransitionAndStore( [=, &miss](ElementsKind from_kind, ElementsKind to_kind) { TransitionElementsKind(receiver, map, from_kind, to_kind, &miss); EmitElementStore(receiver, key, value, to_kind, store_mode, &miss, - context); + context, nullptr); }); Return(value); } @@ -280,7 +281,8 @@ TF_BUILTIN(ElementsTransitionAndStore_NoTransitionHandleCOW, V(BIGINT64_ELEMENTS) void HandlerBuiltinsAssembler::DispatchByElementsKind( - TNode<Int32T> elements_kind, const ElementsKindSwitchCase& case_function) { + TNode<Int32T> elements_kind, const ElementsKindSwitchCase& case_function, + bool handle_typed_elements_kind) { Label next(this), if_unknown_type(this, Label::kDeferred); int32_t elements_kinds[] = { @@ -300,6 +302,8 @@ void HandlerBuiltinsAssembler::DispatchByElementsKind( }; STATIC_ASSERT(arraysize(elements_kinds) == arraysize(elements_kind_labels)); + // TODO(mythria): Do not emit cases for typed elements kind when + // handle_typed_elements is false to decrease the size of the jump table. Switch(elements_kind, &if_unknown_type, elements_kinds, elements_kind_labels, arraysize(elements_kinds)); @@ -310,6 +314,9 @@ void HandlerBuiltinsAssembler::DispatchByElementsKind( IsFrozenOrSealedElementsKindUnchecked(KIND)) { \ /* Disable support for frozen or sealed elements kinds. */ \ Unreachable(); \ + } else if (!handle_typed_elements_kind && \ + IsTypedArrayElementsKind(KIND)) { \ + Unreachable(); \ } else { \ case_function(KIND); \ Goto(&next); \ @@ -340,17 +347,26 @@ void HandlerBuiltinsAssembler::Generate_StoreFastElementIC( Label miss(this); + bool handle_typed_elements_kind = + store_mode == STANDARD_STORE || store_mode == STORE_IGNORE_OUT_OF_BOUNDS; + // For typed arrays maybe_converted_value contains the value obtained after + // calling ToNumber. We should pass the converted value to the runtime to + // avoid doing the user visible conversion again. + VARIABLE(maybe_converted_value, MachineRepresentation::kTagged, value); + maybe_converted_value.Bind(value); // TODO(v8:8481): Pass elements_kind in feedback vector slots. - DispatchByElementsKind(LoadElementsKind(receiver), - [=, &miss](ElementsKind elements_kind) { - EmitElementStore(receiver, key, value, elements_kind, - store_mode, &miss, context); - }); + DispatchByElementsKind( + LoadElementsKind(receiver), + [=, &miss, &maybe_converted_value](ElementsKind elements_kind) { + EmitElementStore(receiver, key, value, elements_kind, store_mode, &miss, + context, &maybe_converted_value); + }, + handle_typed_elements_kind); Return(value); BIND(&miss); - TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, value, slot, vector, - receiver, key); + TailCallRuntime(Runtime::kKeyedStoreIC_Miss, context, + maybe_converted_value.value(), slot, vector, receiver, key); } TF_BUILTIN(StoreFastElementIC_Standard, HandlerBuiltinsAssembler) { diff --git a/deps/v8/src/builtins/builtins-internal-gen.cc b/deps/v8/src/builtins/builtins-internal-gen.cc index baaadb722a..8d22767b58 100644 --- a/deps/v8/src/builtins/builtins-internal-gen.cc +++ b/deps/v8/src/builtins/builtins-internal-gen.cc @@ -614,8 +614,9 @@ class SetOrCopyDataPropertiesAssembler : public CodeStubAssembler { Label if_done(this), if_noelements(this), if_sourcenotjsobject(this, Label::kDeferred); - // JSValue wrappers for numbers don't have any enumerable own properties, - // so we can immediately skip the whole operation if {source} is a Smi. + // JSPrimitiveWrapper wrappers for numbers don't have any enumerable own + // properties, so we can immediately skip the whole operation if {source} is + // a Smi. GotoIf(TaggedIsSmi(source), &if_done); // Otherwise check if {source} is a proper JSObject, and if not, defer @@ -809,17 +810,49 @@ TF_BUILTIN(AdaptorWithBuiltinExitFrame, CodeStubAssembler) { TF_BUILTIN(AllocateInYoungGeneration, CodeStubAssembler) { TNode<IntPtrT> requested_size = UncheckedCast<IntPtrT>(Parameter(Descriptor::kRequestedSize)); + CSA_CHECK(this, IsValidPositiveSmi(requested_size)); + TNode<Smi> allocation_flags = + SmiConstant(Smi::FromInt(AllocateDoubleAlignFlag::encode(false) | + AllowLargeObjectAllocationFlag::encode(true))); TailCallRuntime(Runtime::kAllocateInYoungGeneration, NoContextConstant(), - SmiFromIntPtr(requested_size)); + SmiFromIntPtr(requested_size), allocation_flags); +} + +TF_BUILTIN(AllocateRegularInYoungGeneration, CodeStubAssembler) { + TNode<IntPtrT> requested_size = + UncheckedCast<IntPtrT>(Parameter(Descriptor::kRequestedSize)); + CSA_CHECK(this, IsValidPositiveSmi(requested_size)); + + TNode<Smi> allocation_flags = + SmiConstant(Smi::FromInt(AllocateDoubleAlignFlag::encode(false) | + AllowLargeObjectAllocationFlag::encode(false))); + TailCallRuntime(Runtime::kAllocateInYoungGeneration, NoContextConstant(), + SmiFromIntPtr(requested_size), allocation_flags); } TF_BUILTIN(AllocateInOldGeneration, CodeStubAssembler) { TNode<IntPtrT> requested_size = UncheckedCast<IntPtrT>(Parameter(Descriptor::kRequestedSize)); + CSA_CHECK(this, IsValidPositiveSmi(requested_size)); + + TNode<Smi> runtime_flags = + SmiConstant(Smi::FromInt(AllocateDoubleAlignFlag::encode(false) | + AllowLargeObjectAllocationFlag::encode(true))); + TailCallRuntime(Runtime::kAllocateInOldGeneration, NoContextConstant(), + SmiFromIntPtr(requested_size), runtime_flags); +} + +TF_BUILTIN(AllocateRegularInOldGeneration, CodeStubAssembler) { + TNode<IntPtrT> requested_size = + UncheckedCast<IntPtrT>(Parameter(Descriptor::kRequestedSize)); + CSA_CHECK(this, IsValidPositiveSmi(requested_size)); + TNode<Smi> runtime_flags = + SmiConstant(Smi::FromInt(AllocateDoubleAlignFlag::encode(false) | + AllowLargeObjectAllocationFlag::encode(false))); TailCallRuntime(Runtime::kAllocateInOldGeneration, NoContextConstant(), - SmiFromIntPtr(requested_size), SmiConstant(0)); + SmiFromIntPtr(requested_size), runtime_flags); } TF_BUILTIN(Abort, CodeStubAssembler) { @@ -827,9 +860,9 @@ TF_BUILTIN(Abort, CodeStubAssembler) { TailCallRuntime(Runtime::kAbort, NoContextConstant(), message_id); } -TF_BUILTIN(AbortJS, CodeStubAssembler) { +TF_BUILTIN(AbortCSAAssert, CodeStubAssembler) { TNode<String> message = CAST(Parameter(Descriptor::kMessageOrMessageId)); - TailCallRuntime(Runtime::kAbortJS, NoContextConstant(), message); + TailCallRuntime(Runtime::kAbortCSAAssert, NoContextConstant(), message); } void Builtins::Generate_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit( @@ -907,6 +940,8 @@ TF_BUILTIN(GetProperty, CodeStubAssembler) { Node* object = Parameter(Descriptor::kObject); Node* key = Parameter(Descriptor::kKey); Node* context = Parameter(Descriptor::kContext); + // TODO(duongn): consider tailcalling to GetPropertyWithReceiver(object, + // object, key, OnNonExistent::kReturnUndefined). Label if_notfound(this), if_proxy(this, Label::kDeferred), if_slow(this, Label::kDeferred); @@ -932,7 +967,7 @@ TF_BUILTIN(GetProperty, CodeStubAssembler) { Goto(if_bailout); }; - TryPrototypeChainLookup(object, key, lookup_property_in_holder, + TryPrototypeChainLookup(object, object, key, lookup_property_in_holder, lookup_element_in_holder, &if_notfound, &if_slow, &if_proxy); @@ -955,6 +990,74 @@ TF_BUILTIN(GetProperty, CodeStubAssembler) { } } +// ES6 [[Get]] operation with Receiver. +TF_BUILTIN(GetPropertyWithReceiver, CodeStubAssembler) { + Node* object = Parameter(Descriptor::kObject); + Node* key = Parameter(Descriptor::kKey); + Node* context = Parameter(Descriptor::kContext); + Node* receiver = Parameter(Descriptor::kReceiver); + Node* on_non_existent = Parameter(Descriptor::kOnNonExistent); + Label if_notfound(this), if_proxy(this, Label::kDeferred), + if_slow(this, Label::kDeferred); + + CodeStubAssembler::LookupInHolder lookup_property_in_holder = + [=](Node* receiver, Node* holder, Node* holder_map, + Node* holder_instance_type, Node* unique_name, Label* next_holder, + Label* if_bailout) { + VARIABLE(var_value, MachineRepresentation::kTagged); + Label if_found(this); + TryGetOwnProperty(context, receiver, holder, holder_map, + holder_instance_type, unique_name, &if_found, + &var_value, next_holder, if_bailout); + BIND(&if_found); + Return(var_value.value()); + }; + + CodeStubAssembler::LookupInHolder lookup_element_in_holder = + [=](Node* receiver, Node* holder, Node* holder_map, + Node* holder_instance_type, Node* index, Label* next_holder, + Label* if_bailout) { + // Not supported yet. + Use(next_holder); + Goto(if_bailout); + }; + + TryPrototypeChainLookup(receiver, object, key, lookup_property_in_holder, + lookup_element_in_holder, &if_notfound, &if_slow, + &if_proxy); + + BIND(&if_notfound); + Label throw_reference_error(this); + GotoIf(WordEqual(on_non_existent, + SmiConstant(OnNonExistent::kThrowReferenceError)), + &throw_reference_error); + CSA_ASSERT(this, WordEqual(on_non_existent, + SmiConstant(OnNonExistent::kReturnUndefined))); + Return(UndefinedConstant()); + + BIND(&throw_reference_error); + Return(CallRuntime(Runtime::kThrowReferenceError, context, key)); + + BIND(&if_slow); + TailCallRuntime(Runtime::kGetPropertyWithReceiver, context, object, key, + receiver, on_non_existent); + + BIND(&if_proxy); + { + // Convert the {key} to a Name first. + Node* name = CallBuiltin(Builtins::kToName, context, key); + + // Proxy cannot handle private symbol so bailout. + GotoIf(IsPrivateSymbol(name), &if_slow); + + // The {object} is a JSProxy instance, look up the {name} on it, passing + // {object} both as receiver and holder. If {name} is absent we can safely + // return undefined from here. + TailCallBuiltin(Builtins::kProxyGetProperty, context, object, name, + receiver, on_non_existent); + } +} + // ES6 [[Set]] operation. TF_BUILTIN(SetProperty, CodeStubAssembler) { TNode<Context> context = CAST(Parameter(Descriptor::kContext)); diff --git a/deps/v8/src/builtins/builtins-intl.cc b/deps/v8/src/builtins/builtins-intl.cc index 882afa3c32..ff8e96f4f5 100644 --- a/deps/v8/src/builtins/builtins-intl.cc +++ b/deps/v8/src/builtins/builtins-intl.cc @@ -276,15 +276,14 @@ Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate, // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget, // "%<T>Prototype%", ...). - Handle<JSObject> obj; + Handle<Map> map; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, obj, - JSObject::New(target, new_target, Handle<AllocationSite>::null())); - Handle<T> format = Handle<T>::cast(obj); + isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); // 3. Perform ? Initialize<T>(Format, locales, options). - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, format, T::Initialize(isolate, format, locales, options)); + Handle<T> format; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, format, + T::New(isolate, map, locales, options)); // 4. Let this be the this value. Handle<Object> receiver = args.receiver(); @@ -351,21 +350,17 @@ Object DisallowCallConstructor(BuiltinArguments args, Isolate* isolate, Handle<JSFunction> target = args.target(); Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target()); - Handle<JSObject> obj; + Handle<Map> map; // 2. Let result be OrdinaryCreateFromConstructor(NewTarget, // "%<T>Prototype%"). ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, obj, - JSObject::New(target, new_target, Handle<AllocationSite>::null())); - Handle<T> result = Handle<T>::cast(obj); - result->set_flags(0); + isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); - // 3. Return Initialize<T>(t, locales, options). - RETURN_RESULT_OR_FAILURE(isolate, - T::Initialize(isolate, result, locales, options)); + // 3. Return New<T>(t, locales, options). + RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options)); } /** @@ -387,14 +382,11 @@ Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) { Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); - Handle<JSObject> obj; + Handle<Map> map; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, obj, - JSObject::New(target, new_target, Handle<AllocationSite>::null())); - Handle<T> result = Handle<T>::cast(obj); + isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); - RETURN_RESULT_OR_FAILURE(isolate, - T::Initialize(isolate, result, locales, options)); + RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options)); } } // namespace @@ -591,12 +583,11 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate, Handle<JSFunction> constructor, Handle<JSReceiver> new_target, Handle<Object> tag, Handle<Object> options) { - Handle<JSObject> locale; + Handle<Map> map; // 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, // %LocalePrototype%, internalSlotsList). ASSIGN_RETURN_ON_EXCEPTION( - isolate, locale, - JSObject::New(constructor, new_target, Handle<AllocationSite>::null()), + isolate, map, JSFunction::GetDerivedMap(isolate, constructor, new_target), JSLocale); // 7. If Type(tag) is not String or Object, throw a TypeError exception. @@ -628,8 +619,7 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate, Object::ToObject(isolate, options), JSLocale); } - return JSLocale::Initialize(isolate, Handle<JSLocale>::cast(locale), - locale_string, options_object); + return JSLocale::New(isolate, map, locale_string, options_object); } } // namespace diff --git a/deps/v8/src/builtins/builtins-iterator-gen.cc b/deps/v8/src/builtins/builtins-iterator-gen.cc index 0484501bfb..b3d8e27dbc 100644 --- a/deps/v8/src/builtins/builtins-iterator-gen.cc +++ b/deps/v8/src/builtins/builtins-iterator-gen.cc @@ -75,7 +75,7 @@ IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context, } } -TNode<Object> IteratorBuiltinsAssembler::IteratorStep( +TNode<JSReceiver> IteratorBuiltinsAssembler::IteratorStep( Node* context, const IteratorRecord& iterator, Label* if_done, Node* fast_iterator_result_map, Label* if_exception, Variable* exception) { DCHECK_NOT_NULL(if_done); @@ -125,23 +125,21 @@ TNode<Object> IteratorBuiltinsAssembler::IteratorStep( } BIND(&return_result); - return UncheckedCast<Object>(result); + return CAST(result); } -Node* IteratorBuiltinsAssembler::IteratorValue(Node* context, Node* result, - Node* fast_iterator_result_map, - Label* if_exception, - Variable* exception) { - CSA_ASSERT(this, IsJSReceiver(result)); - +TNode<Object> IteratorBuiltinsAssembler::IteratorValue( + TNode<Context> context, TNode<JSReceiver> result, + base::Optional<TNode<Map>> fast_iterator_result_map, Label* if_exception, + Variable* exception) { Label exit(this); - VARIABLE(var_value, MachineRepresentation::kTagged); - if (fast_iterator_result_map != nullptr) { + TVARIABLE(Object, var_value); + if (fast_iterator_result_map) { // Fast iterator result case: Label if_generic(this); Node* map = LoadMap(result); - GotoIfNot(WordEqual(map, fast_iterator_result_map), &if_generic); - var_value.Bind(LoadObjectField(result, JSIteratorResult::kValueOffset)); + GotoIfNot(WordEqual(map, *fast_iterator_result_map), &if_generic); + var_value = LoadObjectField(result, JSIteratorResult::kValueOffset); Goto(&exit); BIND(&if_generic); @@ -149,9 +147,10 @@ Node* IteratorBuiltinsAssembler::IteratorValue(Node* context, Node* result, // Generic iterator result case: { - Node* value = GetProperty(context, result, factory()->value_string()); + TNode<Object> value = + GetProperty(context, result, factory()->value_string()); GotoIfException(value, if_exception, exception); - var_value.Bind(value); + var_value = value; Goto(&exit); } @@ -217,10 +216,10 @@ TNode<JSArray> IteratorBuiltinsAssembler::IterableToList( BIND(&loop_start); { // a. Set next to ? IteratorStep(iteratorRecord). - TNode<Object> next = IteratorStep(context, iterator_record, &done); + TNode<JSReceiver> next = IteratorStep(context, iterator_record, &done); // b. If next is not false, then // i. Let nextValue be ? IteratorValue(next). - TNode<Object> next_value = CAST(IteratorValue(context, next)); + TNode<Object> next_value = IteratorValue(context, next); // ii. Append nextValue to the end of the List values. values.Push(next_value); Goto(&loop_start); diff --git a/deps/v8/src/builtins/builtins-iterator-gen.h b/deps/v8/src/builtins/builtins-iterator-gen.h index cf421dc5b7..db86c65385 100644 --- a/deps/v8/src/builtins/builtins-iterator-gen.h +++ b/deps/v8/src/builtins/builtins-iterator-gen.h @@ -32,18 +32,19 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler { Variable* exception = nullptr); // https://tc39.github.io/ecma262/#sec-iteratorstep - // Returns `false` if the iterator is done, otherwise returns an - // iterator result. + // If the iterator is done, goto {if_done}, otherwise returns an iterator + // result. // `fast_iterator_result_map` refers to the map for the JSIteratorResult // object, loaded from the native context. - TNode<Object> IteratorStep(Node* context, const IteratorRecord& iterator, - Label* if_done, - Node* fast_iterator_result_map = nullptr, - Label* if_exception = nullptr, - Variable* exception = nullptr); - - TNode<Object> IteratorStep(Node* context, const IteratorRecord& iterator, - Node* fast_iterator_result_map, Label* if_done) { + TNode<JSReceiver> IteratorStep(Node* context, const IteratorRecord& iterator, + Label* if_done, + Node* fast_iterator_result_map = nullptr, + Label* if_exception = nullptr, + Variable* exception = nullptr); + + TNode<JSReceiver> IteratorStep(Node* context, const IteratorRecord& iterator, + Node* fast_iterator_result_map, + Label* if_done) { return IteratorStep(context, iterator, if_done, fast_iterator_result_map); } @@ -51,10 +52,10 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler { // Return the `value` field from an iterator. // `fast_iterator_result_map` refers to the map for the JSIteratorResult // object, loaded from the native context. - Node* IteratorValue(Node* context, Node* result, - Node* fast_iterator_result_map = nullptr, - Label* if_exception = nullptr, - Variable* exception = nullptr); + TNode<Object> IteratorValue( + TNode<Context> context, TNode<JSReceiver> result, + base::Optional<TNode<Map>> fast_iterator_result_map = base::nullopt, + Label* if_exception = nullptr, Variable* exception = nullptr); // https://tc39.github.io/ecma262/#sec-iteratorclose void IteratorCloseOnException(Node* context, const IteratorRecord& iterator, diff --git a/deps/v8/src/builtins/builtins-math.cc b/deps/v8/src/builtins/builtins-math.cc index 6d3274a4a5..cce780ab9f 100644 --- a/deps/v8/src/builtins/builtins-math.cc +++ b/deps/v8/src/builtins/builtins-math.cc @@ -20,7 +20,6 @@ BUILTIN(MathHypot) { if (length == 0) return Smi::kZero; DCHECK_LT(0, length); double max = 0; - bool one_arg_is_nan = false; std::vector<double> abs_values; abs_values.reserve(length); for (int i = 0; i < length; i++) { @@ -28,29 +27,20 @@ BUILTIN(MathHypot) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(isolate, x)); double abs_value = std::abs(x->Number()); - - if (std::isnan(abs_value)) { - one_arg_is_nan = true; - } else { - abs_values.push_back(abs_value); - if (max < abs_value) { - max = abs_value; - } + abs_values.push_back(abs_value); + // Use negation here to make sure that {max} is NaN + // in the end in case any of the arguments was NaN. + if (!(abs_value <= max)) { + max = abs_value; } } - if (max == V8_INFINITY) { - return *isolate->factory()->NewNumber(V8_INFINITY); - } - - if (one_arg_is_nan) { - return ReadOnlyRoots(isolate).nan_value(); - } - if (max == 0) { return Smi::kZero; + } else if (max == V8_INFINITY) { + return ReadOnlyRoots(isolate).infinity_value(); } - DCHECK_GT(max, 0); + DCHECK(!(max <= 0)); // Kahan summation to avoid rounding errors. // Normalize the numbers to the largest one to avoid overflow. diff --git a/deps/v8/src/builtins/builtins-number-gen.cc b/deps/v8/src/builtins/builtins-number-gen.cc index 5b3af79f00..f5c4477c23 100644 --- a/deps/v8/src/builtins/builtins-number-gen.cc +++ b/deps/v8/src/builtins/builtins-number-gen.cc @@ -315,8 +315,8 @@ TF_BUILTIN(NumberParseInt, CodeStubAssembler) { // ES6 #sec-number.prototype.valueof TF_BUILTIN(NumberPrototypeValueOf, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Node* result = ToThisValue(context, receiver, PrimitiveType::kNumber, "Number.prototype.valueOf"); @@ -538,8 +538,8 @@ TF_BUILTIN(Add, AddStubAssembler) { BIND(&do_bigint_add); { - Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(), - var_right.value(), SmiConstant(Operation::kAdd))); + TailCallBuiltin(Builtins::kBigIntAdd, context, var_left.value(), + var_right.value()); } BIND(&do_double_add); @@ -996,8 +996,8 @@ TF_BUILTIN(Equal, CodeStubAssembler) { } TF_BUILTIN(StrictEqual, CodeStubAssembler) { - Node* lhs = Parameter(Descriptor::kLeft); - Node* rhs = Parameter(Descriptor::kRight); + TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft)); + TNode<Object> rhs = CAST(Parameter(Descriptor::kRight)); Return(StrictEqual(lhs, rhs)); } diff --git a/deps/v8/src/builtins/builtins-number.cc b/deps/v8/src/builtins/builtins-number.cc index 929e686604..d2fb0ff74c 100644 --- a/deps/v8/src/builtins/builtins-number.cc +++ b/deps/v8/src/builtins/builtins-number.cc @@ -25,8 +25,8 @@ BUILTIN(NumberPrototypeToExponential) { Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); // Unwrap the receiver {value}. - if (value->IsJSValue()) { - value = handle(Handle<JSValue>::cast(value)->value(), isolate); + if (value->IsJSPrimitiveWrapper()) { + value = handle(Handle<JSPrimitiveWrapper>::cast(value)->value(), isolate); } if (!value->IsNumber()) { THROW_NEW_ERROR_RETURN_FAILURE( @@ -70,8 +70,8 @@ BUILTIN(NumberPrototypeToFixed) { Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); // Unwrap the receiver {value}. - if (value->IsJSValue()) { - value = handle(Handle<JSValue>::cast(value)->value(), isolate); + if (value->IsJSPrimitiveWrapper()) { + value = handle(Handle<JSPrimitiveWrapper>::cast(value)->value(), isolate); } if (!value->IsNumber()) { THROW_NEW_ERROR_RETURN_FAILURE( @@ -117,8 +117,8 @@ BUILTIN(NumberPrototypeToLocaleString) { Handle<Object> value = args.at(0); // Unwrap the receiver {value}. - if (value->IsJSValue()) { - value = handle(Handle<JSValue>::cast(value)->value(), isolate); + if (value->IsJSPrimitiveWrapper()) { + value = handle(Handle<JSPrimitiveWrapper>::cast(value)->value(), isolate); } // 1. Let x be ? thisNumberValue(this value) if (!value->IsNumber()) { @@ -147,8 +147,8 @@ BUILTIN(NumberPrototypeToPrecision) { Handle<Object> precision = args.atOrUndefined(isolate, 1); // Unwrap the receiver {value}. - if (value->IsJSValue()) { - value = handle(Handle<JSValue>::cast(value)->value(), isolate); + if (value->IsJSPrimitiveWrapper()) { + value = handle(Handle<JSPrimitiveWrapper>::cast(value)->value(), isolate); } if (!value->IsNumber()) { THROW_NEW_ERROR_RETURN_FAILURE( @@ -192,8 +192,8 @@ BUILTIN(NumberPrototypeToString) { Handle<Object> radix = args.atOrUndefined(isolate, 1); // Unwrap the receiver {value}. - if (value->IsJSValue()) { - value = handle(Handle<JSValue>::cast(value)->value(), isolate); + if (value->IsJSPrimitiveWrapper()) { + value = handle(Handle<JSPrimitiveWrapper>::cast(value)->value(), isolate); } if (!value->IsNumber()) { THROW_NEW_ERROR_RETURN_FAILURE( diff --git a/deps/v8/src/builtins/builtins-object-gen.cc b/deps/v8/src/builtins/builtins-object-gen.cc index 314331d498..8d59ee3bd1 100644 --- a/deps/v8/src/builtins/builtins-object-gen.cc +++ b/deps/v8/src/builtins/builtins-object-gen.cc @@ -65,8 +65,6 @@ class ObjectEntriesValuesBuiltinsAssembler : public ObjectBuiltinsAssembler { TNode<BoolT> IsPropertyKindData(TNode<Uint32T> kind); - TNode<Uint32T> HasHiddenPrototype(TNode<Map> map); - TNode<Uint32T> LoadPropertyKind(TNode<Uint32T> details) { return DecodeWord32<PropertyDetails::KindField>(details); } @@ -185,12 +183,6 @@ TNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindData( return Word32Equal(kind, Int32Constant(PropertyKind::kData)); } -TNode<Uint32T> ObjectEntriesValuesBuiltinsAssembler::HasHiddenPrototype( - TNode<Map> map) { - TNode<Uint32T> bit_field2 = Unsigned(LoadMapBitField2(map)); - return DecodeWord32<Map::HasHiddenPrototypeBit>(bit_field2); -} - void ObjectEntriesValuesBuiltinsAssembler::GetOwnValuesOrEntries( TNode<Context> context, TNode<Object> maybe_object, CollectType collect_type) { @@ -254,7 +246,6 @@ void ObjectEntriesValuesBuiltinsAssembler::GotoIfMapHasSlowProperties( TNode<Map> map, Label* if_slow) { GotoIf(IsStringWrapperElementsKind(map), if_slow); GotoIf(IsSpecialReceiverMap(map), if_slow); - GotoIf(HasHiddenPrototype(map), if_slow); GotoIf(IsDictionaryMap(map), if_slow); } @@ -602,9 +593,19 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { if_fast(this), try_fast(this, Label::kDeferred), if_slow(this, Label::kDeferred), if_join(this); - // Check if the {object} has a usable enum cache. + // Take the slow path if the {object} IsCustomElementsReceiverInstanceType or + // has any elements. GotoIf(TaggedIsSmi(object), &if_slow); Node* object_map = LoadMap(object); + TNode<Int32T> instance_type = LoadMapInstanceType(object_map); + GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &if_slow); + Node* object_elements = LoadElements(object); + GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements); + Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements, + &if_slow); + + // Check if the {object} has a usable enum cache. + BIND(&if_empty_elements); Node* object_bit_field3 = LoadMapBitField3(object_map); Node* object_enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(object_bit_field3); @@ -612,15 +613,7 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { WordEqual(object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel)), &try_fast); - // Ensure that the {object} doesn't have any elements. - CSA_ASSERT(this, IsJSObjectMap(object_map)); - Node* object_elements = LoadElements(object); - GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements); - Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements, - &if_slow); - // Check whether all own properties are enumerable. - BIND(&if_empty_elements); Node* number_descriptors = DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(object_bit_field3); GotoIfNot(WordEqual(object_enum_length, number_descriptors), &if_slow); @@ -728,11 +721,11 @@ TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) { // invoke the ToObject builtin, which raises the appropriate error. // Otherwise we don't need to invoke ToObject, since {receiver} is // either already a JSReceiver, in which case ToObject is a no-op, - // or it's a Primitive and ToObject would allocate a fresh JSValue + // or it's a Primitive and ToObject would allocate a fresh JSPrimitiveWrapper // wrapper, which wouldn't be identical to any existing JSReceiver // found in the prototype chain of {value}, hence it will return // false no matter if we search for the Primitive {receiver} or - // a newly allocated JSValue wrapper for {receiver}. + // a newly allocated JSPrimitiveWrapper wrapper for {receiver}. GotoIf(IsNull(receiver), &if_receiverisnullorundefined); GotoIf(IsUndefined(receiver), &if_receiverisnullorundefined); @@ -794,7 +787,7 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { {JS_SPECIAL_API_OBJECT_TYPE, &if_apiobject}, {JS_PROXY_TYPE, &if_proxy}, {JS_ERROR_TYPE, &if_error}, - {JS_VALUE_TYPE, &if_value}}; + {JS_PRIMITIVE_WRAPPER_TYPE, &if_value}}; size_t const kNumCases = arraysize(kJumpTable); Label* case_labels[kNumCases]; int32_t case_values[kNumCases]; @@ -996,7 +989,7 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { if_value_is_bigint(this, Label::kDeferred), if_value_is_string(this, Label::kDeferred); - Node* receiver_value = LoadJSValueValue(receiver); + Node* receiver_value = LoadJSPrimitiveWrapperValue(receiver); // We need to start with the object to see if the value was a subclass // which might have interesting properties. var_holder.Bind(receiver); @@ -1346,10 +1339,15 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) { StoreObjectFieldNoWriteBarrier( result, JSGeneratorObject::kParametersAndRegistersOffset, parameters_and_registers); + Node* resume_mode = SmiConstant(JSGeneratorObject::ResumeMode::kNext); + StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kResumeModeOffset, + resume_mode); Node* executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting); StoreObjectFieldNoWriteBarrier(result, JSGeneratorObject::kContinuationOffset, executing); - GotoIfNot(HasInstanceType(maybe_map, JS_ASYNC_GENERATOR_OBJECT_TYPE), &done); + GotoIfNot(InstanceTypeEqual(LoadMapInstanceType(maybe_map), + JS_ASYNC_GENERATOR_OBJECT_TYPE), + &done); StoreObjectFieldNoWriteBarrier( result, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(0)); Goto(&done); diff --git a/deps/v8/src/builtins/builtins-object.cc b/deps/v8/src/builtins/builtins-object.cc index 59e4373f98..1ca5fffd8d 100644 --- a/deps/v8/src/builtins/builtins-object.cc +++ b/deps/v8/src/builtins/builtins-object.cc @@ -5,7 +5,7 @@ #include "src/builtins/builtins-utils-inl.h" #include "src/builtins/builtins.h" #include "src/codegen/code-factory.h" -#include "src/execution/message-template.h" +#include "src/common/message-template.h" #include "src/heap/heap-inl.h" // For ToBoolean. TODO(jkummerow): Drop. #include "src/logging/counters.h" #include "src/objects/keys.h" @@ -218,52 +218,6 @@ BUILTIN(ObjectFreeze) { return *object; } -// ES section 19.1.2.9 Object.getPrototypeOf ( O ) -BUILTIN(ObjectGetPrototypeOf) { - HandleScope scope(isolate); - Handle<Object> object = args.atOrUndefined(isolate, 1); - - Handle<JSReceiver> receiver; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, - Object::ToObject(isolate, object)); - - RETURN_RESULT_OR_FAILURE(isolate, - JSReceiver::GetPrototype(isolate, receiver)); -} - -// ES6 section 19.1.2.21 Object.setPrototypeOf ( O, proto ) -BUILTIN(ObjectSetPrototypeOf) { - HandleScope scope(isolate); - - // 1. Let O be ? RequireObjectCoercible(O). - Handle<Object> object = args.atOrUndefined(isolate, 1); - if (object->IsNullOrUndefined(isolate)) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, - isolate->factory()->NewStringFromAsciiChecked( - "Object.setPrototypeOf"))); - } - - // 2. If Type(proto) is neither Object nor Null, throw a TypeError exception. - Handle<Object> proto = args.atOrUndefined(isolate, 2); - if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); - } - - // 3. If Type(O) is not Object, return O. - if (!object->IsJSReceiver()) return *object; - Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); - - // 4. Let status be ? O.[[SetPrototypeOf]](proto). - // 5. If status is false, throw a TypeError exception. - MAYBE_RETURN(JSReceiver::SetPrototype(receiver, proto, true, kThrowOnError), - ReadOnlyRoots(isolate).exception()); - - // 6. Return O. - return *receiver; -} - // ES6 section B.2.2.1.1 get Object.prototype.__proto__ BUILTIN(ObjectPrototypeGetProto) { HandleScope scope(isolate); @@ -332,18 +286,6 @@ BUILTIN(ObjectGetOwnPropertySymbols) { return GetOwnPropertyKeys(isolate, args, SKIP_STRINGS); } -// ES6 section 19.1.2.11 Object.isExtensible ( O ) -BUILTIN(ObjectIsExtensible) { - HandleScope scope(isolate); - Handle<Object> object = args.atOrUndefined(isolate, 1); - Maybe<bool> result = - object->IsJSReceiver() - ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object)) - : Just(false); - MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception()); - return isolate->heap()->ToBoolean(result.FromJust()); -} - // ES6 section 19.1.2.12 Object.isFrozen ( O ) BUILTIN(ObjectIsFrozen) { HandleScope scope(isolate); @@ -403,18 +345,6 @@ BUILTIN(ObjectGetOwnPropertyDescriptors) { return *descriptors; } -// ES6 section 19.1.2.15 Object.preventExtensions ( O ) -BUILTIN(ObjectPreventExtensions) { - HandleScope scope(isolate); - Handle<Object> object = args.atOrUndefined(isolate, 1); - if (object->IsJSReceiver()) { - MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object), - kThrowOnError), - ReadOnlyRoots(isolate).exception()); - } - return *object; -} - // ES6 section 19.1.2.17 Object.seal ( O ) BUILTIN(ObjectSeal) { HandleScope scope(isolate); diff --git a/deps/v8/src/builtins/builtins-promise-gen.cc b/deps/v8/src/builtins/builtins-promise-gen.cc index ad70fb1dd1..1339e2dccd 100644 --- a/deps/v8/src/builtins/builtins-promise-gen.cc +++ b/deps/v8/src/builtins/builtins-promise-gen.cc @@ -2062,7 +2062,7 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll( // 5. Let _promiseResolve_ be ? Get(_constructor_, `"resolve"`). TNode<Object> resolve = GetProperty(native_context, constructor, factory()->resolve_string()); - GotoIfException(resolve, if_exception, var_exception); + GotoIfException(resolve, &close_iterator, var_exception); // 6. If IsCallable(_promiseResolve_) is *false*, throw a *TypeError* // exception. @@ -2077,9 +2077,9 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll( // Let next be IteratorStep(iteratorRecord.[[Iterator]]). // If next is an abrupt completion, set iteratorRecord.[[Done]] to true. // ReturnIfAbrupt(next). - Node* const fast_iterator_result_map = - LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX); - Node* const next = iter_assembler.IteratorStep( + TNode<Map> const fast_iterator_result_map = CAST( + LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX)); + TNode<JSReceiver> const next = iter_assembler.IteratorStep( native_context, iterator, &done_loop, fast_iterator_result_map, if_exception, var_exception); @@ -2087,7 +2087,7 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll( // If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to // true. // ReturnIfAbrupt(nextValue). - Node* const next_value = iter_assembler.IteratorValue( + TNode<Object> const next_value = iter_assembler.IteratorValue( native_context, next, fast_iterator_result_map, if_exception, var_exception); @@ -2148,7 +2148,7 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll( &if_slow); GotoIf(IsPromiseSpeciesProtectorCellInvalid(), &if_slow); GotoIf(TaggedIsSmi(next_value), &if_slow); - Node* const next_value_map = LoadMap(next_value); + Node* const next_value_map = LoadMap(CAST(next_value)); BranchIfPromiseThenLookupChainIntact(native_context, next_value_map, &if_fast, &if_slow); @@ -2526,8 +2526,7 @@ TF_BUILTIN(PromiseAllSettledResolveElementClosure, PromiseBuiltinsAssembler) { LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX)); TNode<Map> object_function_map = Cast(LoadObjectField( object_function, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<JSObject> obj = - Cast(AllocateJSObjectFromMap(object_function_map)); + TNode<JSObject> obj = AllocateJSObjectFromMap(object_function_map); // 10. Perform ! CreateDataProperty(obj, "status", "fulfilled"). CallBuiltin(Builtins::kFastCreateDataProperty, context, obj, @@ -2557,8 +2556,7 @@ TF_BUILTIN(PromiseAllSettledRejectElementClosure, PromiseBuiltinsAssembler) { LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX)); TNode<Map> object_function_map = Cast(LoadObjectField( object_function, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<JSObject> obj = - Cast(AllocateJSObjectFromMap(object_function_map)); + TNode<JSObject> obj = AllocateJSObjectFromMap(object_function_map); // 10. Perform ! CreateDataProperty(obj, "status", "rejected"). CallBuiltin(Builtins::kFastCreateDataProperty, context, obj, @@ -2579,7 +2577,7 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) { VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant()); Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + TNode<Context> const context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject, "Promise.race"); @@ -2626,11 +2624,11 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) { // 3. Let _promiseResolve_ be ? Get(_constructor_, `"resolve"`). TNode<Object> resolve = GetProperty(native_context, receiver, factory()->resolve_string()); - GotoIfException(resolve, &reject_promise, &var_exception); + GotoIfException(resolve, &close_iterator, &var_exception); // 4. If IsCallable(_promiseResolve_) is *false*, throw a *TypeError* // exception. - ThrowIfNotCallable(CAST(context), resolve, "resolve"); + ThrowIfNotCallable(context, resolve, "resolve"); var_promise_resolve_function = resolve; Goto(&loop); @@ -2638,13 +2636,13 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) { BIND(&loop); { - Node* const fast_iterator_result_map = LoadContextElement( - native_context, Context::ITERATOR_RESULT_MAP_INDEX); + TNode<Map> const fast_iterator_result_map = CAST(LoadContextElement( + native_context, Context::ITERATOR_RESULT_MAP_INDEX)); // Let next be IteratorStep(iteratorRecord.[[Iterator]]). // If next is an abrupt completion, set iteratorRecord.[[Done]] to true. // ReturnIfAbrupt(next). - Node* const next = iter_assembler.IteratorStep( + TNode<JSReceiver> const next = iter_assembler.IteratorStep( context, iterator, &break_loop, fast_iterator_result_map, &reject_promise, &var_exception); @@ -2652,7 +2650,7 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) { // If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to // true. // ReturnIfAbrupt(nextValue). - Node* const next_value = + TNode<Object> const next_value = iter_assembler.IteratorValue(context, next, fast_iterator_result_map, &reject_promise, &var_exception); diff --git a/deps/v8/src/builtins/builtins-proxy-gen.cc b/deps/v8/src/builtins/builtins-proxy-gen.cc index a1a2f6308f..948540ea5f 100644 --- a/deps/v8/src/builtins/builtins-proxy-gen.cc +++ b/deps/v8/src/builtins/builtins-proxy-gen.cc @@ -13,8 +13,9 @@ namespace v8 { namespace internal { -Node* ProxiesCodeStubAssembler::AllocateProxy(Node* target, Node* handler, - Node* context) { +compiler::TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy( + TNode<Context> context, TNode<JSReceiver> target, + TNode<JSReceiver> handler) { VARIABLE(map, MachineRepresentation::kTagged); Label callable_target(this), constructor_target(this), none_target(this), @@ -53,7 +54,7 @@ Node* ProxiesCodeStubAssembler::AllocateProxy(Node* target, Node* handler, StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kTargetOffset, target); StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHandlerOffset, handler); - return proxy; + return CAST(proxy); } Node* ProxiesCodeStubAssembler::AllocateJSArrayForCodeStubArguments( @@ -121,8 +122,9 @@ Node* ProxiesCodeStubAssembler::CreateProxyRevokeFunctionContext( return context; } -Node* ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(Node* proxy, - Node* context) { +compiler::TNode<JSFunction> +ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(TNode<Context> context, + TNode<JSProxy> proxy) { Node* const native_context = LoadNativeContext(context); Node* const proxy_context = @@ -132,13 +134,8 @@ Node* ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(Node* proxy, Node* const revoke_info = LoadContextElement(native_context, Context::PROXY_REVOKE_SHARED_FUN); - return AllocateFunctionWithMapAndContext(revoke_map, revoke_info, - proxy_context); -} - -Node* ProxiesCodeStubAssembler::GetProxyConstructorJSNewTarget() { - return CodeAssembler::Parameter(static_cast<int>( - Builtin_ProxyConstructor_InterfaceDescriptor::kJSNewTarget)); + return CAST(AllocateFunctionWithMapAndContext(revoke_map, revoke_info, + proxy_context)); } TF_BUILTIN(CallProxy, ProxiesCodeStubAssembler) { @@ -262,9 +259,11 @@ TF_BUILTIN(ConstructProxy, ProxiesCodeStubAssembler) { { ThrowTypeError(context, MessageTemplate::kProxyRevoked, "construct"); } } -Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult( - Node* context, Node* target, Node* proxy, Node* name, Node* trap_result, +void ProxiesCodeStubAssembler::CheckGetSetTrapResult( + TNode<Context> context, TNode<JSReceiver> target, TNode<JSProxy> proxy, + TNode<Name> name, TNode<Object> trap_result, JSProxy::AccessKind access_kind) { + // TODO(mslekova): Think of a better name for the trap_result param. Node* map = LoadMap(target); VARIABLE(var_value, MachineRepresentation::kTagged); VARIABLE(var_details, MachineRepresentation::kWord32); @@ -273,7 +272,7 @@ Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult( Label if_found_value(this), check_in_runtime(this, Label::kDeferred), check_passed(this); - GotoIfNot(IsUniqueNameNoIndex(CAST(name)), &check_in_runtime); + GotoIfNot(IsUniqueNameNoIndex(name), &check_in_runtime); Node* instance_type = LoadInstanceType(target); TryGetOwnProperty(context, target, target, map, instance_type, name, &if_found_value, &var_value, &var_details, &var_raw_value, @@ -366,12 +365,13 @@ Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult( } BIND(&check_passed); - return trap_result; } } -Node* ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target, - Node* proxy, Node* name) { +void ProxiesCodeStubAssembler::CheckHasTrapResult(TNode<Context> context, + TNode<JSReceiver> target, + TNode<JSProxy> proxy, + TNode<Name> name) { Node* target_map = LoadMap(target); VARIABLE(var_value, MachineRepresentation::kTagged); VARIABLE(var_details, MachineRepresentation::kWord32); @@ -383,7 +383,7 @@ Node* ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target, check_in_runtime(this, Label::kDeferred); // 9.a. Let targetDesc be ? target.[[GetOwnProperty]](P). - GotoIfNot(IsUniqueNameNoIndex(CAST(name)), &check_in_runtime); + GotoIfNot(IsUniqueNameNoIndex(name), &check_in_runtime); Node* instance_type = LoadInstanceType(target); TryGetOwnProperty(context, target, target, target_map, instance_type, name, &if_found_value, &var_value, &var_details, &var_raw_value, @@ -419,7 +419,64 @@ Node* ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target, } BIND(&check_passed); - return FalseConstant(); +} + +void ProxiesCodeStubAssembler::CheckDeleteTrapResult(TNode<Context> context, + TNode<JSReceiver> target, + TNode<JSProxy> proxy, + TNode<Name> name) { + TNode<Map> target_map = LoadMap(target); + TVARIABLE(Object, var_value); + TVARIABLE(Uint32T, var_details); + TVARIABLE(Object, var_raw_value); + + Label if_found_value(this, Label::kDeferred), + throw_non_configurable(this, Label::kDeferred), + throw_non_extensible(this, Label::kDeferred), check_passed(this), + check_in_runtime(this, Label::kDeferred); + + // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). + GotoIfNot(IsUniqueNameNoIndex(name), &check_in_runtime); + TNode<Int32T> instance_type = LoadInstanceType(target); + TryGetOwnProperty(context, target, target, target_map, instance_type, name, + &if_found_value, &var_value, &var_details, &var_raw_value, + &check_passed, &check_in_runtime, kReturnAccessorPair); + + // 11. If targetDesc is undefined, return true. + BIND(&if_found_value); + { + // 12. If targetDesc.[[Configurable]] is false, throw a TypeError exception. + TNode<BoolT> non_configurable = IsSetWord32( + var_details.value(), PropertyDetails::kAttributesDontDeleteMask); + GotoIf(non_configurable, &throw_non_configurable); + + // 13. Let extensibleTarget be ? IsExtensible(target). + TNode<BoolT> target_extensible = IsExtensibleMap(target_map); + + // 14. If extensibleTarget is false, throw a TypeError exception. + GotoIfNot(target_extensible, &throw_non_extensible); + Goto(&check_passed); + } + + BIND(&throw_non_configurable); + { + ThrowTypeError(context, + MessageTemplate::kProxyDeletePropertyNonConfigurable, name); + } + + BIND(&throw_non_extensible); + { + ThrowTypeError(context, MessageTemplate::kProxyDeletePropertyNonExtensible, + name); + } + + BIND(&check_in_runtime); + { + CallRuntime(Runtime::kCheckProxyDeleteTrapResult, context, name, target); + Goto(&check_passed); + } + + BIND(&check_passed); } } // namespace internal diff --git a/deps/v8/src/builtins/builtins-proxy-gen.h b/deps/v8/src/builtins/builtins-proxy-gen.h index fcaac7df66..cb51faf575 100644 --- a/deps/v8/src/builtins/builtins-proxy-gen.h +++ b/deps/v8/src/builtins/builtins-proxy-gen.h @@ -17,19 +17,21 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler { explicit ProxiesCodeStubAssembler(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) {} - Node* AllocateProxy(Node* target, Node* handler, Node* context); - Node* AllocateProxyRevokeFunction(Node* proxy, Node* context); + TNode<JSProxy> AllocateProxy(TNode<Context> context, TNode<JSReceiver> target, + TNode<JSReceiver> handler); + TNode<JSFunction> AllocateProxyRevokeFunction(TNode<Context> context, + TNode<JSProxy> proxy); - // Get JSNewTarget parameter for ProxyConstructor builtin (Torque). - // TODO(v8:9120): Remove this once torque support exists - Node* GetProxyConstructorJSNewTarget(); + void CheckGetSetTrapResult(TNode<Context> context, TNode<JSReceiver> target, + TNode<JSProxy> proxy, TNode<Name> name, + TNode<Object> trap_result, + JSProxy::AccessKind access_kind); - Node* CheckGetSetTrapResult(Node* context, Node* target, Node* proxy, - Node* name, Node* trap_result, - JSProxy::AccessKind access_kind); + void CheckHasTrapResult(TNode<Context> context, TNode<JSReceiver> target, + TNode<JSProxy> proxy, TNode<Name> name); - Node* CheckHasTrapResult(Node* context, Node* target, Node* proxy, - Node* name); + void CheckDeleteTrapResult(TNode<Context> context, TNode<JSReceiver> target, + TNode<JSProxy> proxy, TNode<Name> name); protected: enum ProxyRevokeFunctionContextSlot { @@ -37,9 +39,10 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler { kProxyContextLength, }; - Node* AllocateJSArrayForCodeStubArguments(Node* context, - CodeStubArguments& args, Node* argc, - ParameterMode mode); + Node* AllocateJSArrayForCodeStubArguments( + Node* context, + CodeStubArguments& args, // NOLINT(runtime/references) + Node* argc, ParameterMode mode); private: Node* CreateProxyRevokeFunctionContext(Node* proxy, Node* native_context); diff --git a/deps/v8/src/builtins/builtins-reflect.cc b/deps/v8/src/builtins/builtins-reflect.cc index e998652dad..6151fcbd47 100644 --- a/deps/v8/src/builtins/builtins-reflect.cc +++ b/deps/v8/src/builtins/builtins-reflect.cc @@ -46,53 +46,6 @@ BUILTIN(ReflectDefineProperty) { return *isolate->factory()->ToBoolean(result.FromJust()); } -// ES6 section 26.1.4 Reflect.deleteProperty -BUILTIN(ReflectDeleteProperty) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - Handle<Object> target = args.at(1); - Handle<Object> key = args.at(2); - - if (!target->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, - isolate->factory()->NewStringFromAsciiChecked( - "Reflect.deleteProperty"))); - } - - Handle<Name> name; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, - Object::ToName(isolate, key)); - - Maybe<bool> result = JSReceiver::DeletePropertyOrElement( - Handle<JSReceiver>::cast(target), name, LanguageMode::kSloppy); - MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception()); - return *isolate->factory()->ToBoolean(result.FromJust()); -} - -// ES6 section 26.1.6 Reflect.get -BUILTIN(ReflectGet) { - HandleScope scope(isolate); - Handle<Object> target = args.atOrUndefined(isolate, 1); - Handle<Object> key = args.atOrUndefined(isolate, 2); - Handle<Object> receiver = args.length() > 3 ? args.at(3) : target; - - if (!target->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, - isolate->factory()->NewStringFromAsciiChecked( - "Reflect.get"))); - } - - Handle<Name> name; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, - Object::ToName(isolate, key)); - - RETURN_RESULT_OR_FAILURE( - isolate, Object::GetPropertyOrElement(receiver, name, - Handle<JSReceiver>::cast(target))); -} - // ES6 section 26.1.7 Reflect.getOwnPropertyDescriptor BUILTIN(ReflectGetOwnPropertyDescriptor) { HandleScope scope(isolate); @@ -119,42 +72,6 @@ BUILTIN(ReflectGetOwnPropertyDescriptor) { return *desc.ToObject(isolate); } -// ES6 section 26.1.8 Reflect.getPrototypeOf -BUILTIN(ReflectGetPrototypeOf) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - Handle<Object> target = args.at(1); - - if (!target->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, - isolate->factory()->NewStringFromAsciiChecked( - "Reflect.getPrototypeOf"))); - } - Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(target); - RETURN_RESULT_OR_FAILURE(isolate, - JSReceiver::GetPrototype(isolate, receiver)); -} - -// ES6 section 26.1.10 Reflect.isExtensible -BUILTIN(ReflectIsExtensible) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - Handle<Object> target = args.at(1); - - if (!target->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, - isolate->factory()->NewStringFromAsciiChecked( - "Reflect.isExtensible"))); - } - - Maybe<bool> result = - JSReceiver::IsExtensible(Handle<JSReceiver>::cast(target)); - MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception()); - return *isolate->factory()->ToBoolean(result.FromJust()); -} - // ES6 section 26.1.11 Reflect.ownKeys BUILTIN(ReflectOwnKeys) { HandleScope scope(isolate); @@ -177,25 +94,6 @@ BUILTIN(ReflectOwnKeys) { return *isolate->factory()->NewJSArrayWithElements(keys); } -// ES6 section 26.1.12 Reflect.preventExtensions -BUILTIN(ReflectPreventExtensions) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - Handle<Object> target = args.at(1); - - if (!target->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, - isolate->factory()->NewStringFromAsciiChecked( - "Reflect.preventExtensions"))); - } - - Maybe<bool> result = JSReceiver::PreventExtensions( - Handle<JSReceiver>::cast(target), kDontThrow); - MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception()); - return *isolate->factory()->ToBoolean(result.FromJust()); -} - // ES6 section 26.1.13 Reflect.set BUILTIN(ReflectSet) { HandleScope scope(isolate); @@ -223,30 +121,5 @@ BUILTIN(ReflectSet) { return *isolate->factory()->ToBoolean(result.FromJust()); } -// ES6 section 26.1.14 Reflect.setPrototypeOf -BUILTIN(ReflectSetPrototypeOf) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - Handle<Object> target = args.at(1); - Handle<Object> proto = args.at(2); - - if (!target->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, - isolate->factory()->NewStringFromAsciiChecked( - "Reflect.setPrototypeOf"))); - } - - if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); - } - - Maybe<bool> result = JSReceiver::SetPrototype( - Handle<JSReceiver>::cast(target), proto, true, kDontThrow); - MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception()); - return *isolate->factory()->ToBoolean(result.FromJust()); -} - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/builtins-regexp-gen.cc b/deps/v8/src/builtins/builtins-regexp-gen.cc index 51ee2796e6..d53518ff7e 100644 --- a/deps/v8/src/builtins/builtins-regexp-gen.cc +++ b/deps/v8/src/builtins/builtins-regexp-gen.cc @@ -15,7 +15,7 @@ #include "src/objects/js-regexp-string-iterator.h" #include "src/objects/js-regexp.h" #include "src/objects/regexp-match-info.h" -#include "src/regexp/regexp-macro-assembler.h" +#include "src/regexp/regexp.h" namespace v8 { namespace internal { @@ -94,12 +94,12 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpCreate(TNode<Context> context, TNode<String> pattern = Select<String>( IsUndefined(maybe_string), [=] { return EmptyStringConstant(); }, [=] { return ToString_Inline(context, maybe_string); }); - TNode<Object> regexp = CAST(AllocateJSObjectFromMap(initial_map)); + TNode<JSObject> regexp = AllocateJSObjectFromMap(initial_map); return CallRuntime(Runtime::kRegExpInitializeAndCompile, context, regexp, pattern, flags); } -TNode<Object> RegExpBuiltinsAssembler::FastLoadLastIndex( +TNode<Object> RegExpBuiltinsAssembler::FastLoadLastIndexBeforeSmiCheck( TNode<JSRegExp> regexp) { // Load the in-object field. static const int field_offset = @@ -121,23 +121,27 @@ TNode<Object> RegExpBuiltinsAssembler::LoadLastIndex(TNode<Context> context, // The fast-path of StoreLastIndex when regexp is guaranteed to be an unmodified // JSRegExp instance. -void RegExpBuiltinsAssembler::FastStoreLastIndex(Node* regexp, Node* value) { +void RegExpBuiltinsAssembler::FastStoreLastIndex(TNode<JSRegExp> regexp, + TNode<Smi> value) { // Store the in-object field. static const int field_offset = JSRegExp::kSize + JSRegExp::kLastIndexFieldIndex * kTaggedSize; StoreObjectField(regexp, field_offset, value); } -void RegExpBuiltinsAssembler::SlowStoreLastIndex(Node* context, Node* regexp, - Node* value) { - Node* const name = HeapConstant(isolate()->factory()->lastIndex_string()); - SetPropertyStrict(CAST(context), CAST(regexp), CAST(name), CAST(value)); +void RegExpBuiltinsAssembler::SlowStoreLastIndex(SloppyTNode<Context> context, + SloppyTNode<Object> regexp, + SloppyTNode<Number> value) { + TNode<Name> name = HeapConstant(isolate()->factory()->lastIndex_string()); + SetPropertyStrict(context, regexp, name, value); } -void RegExpBuiltinsAssembler::StoreLastIndex(Node* context, Node* regexp, - Node* value, bool is_fastpath) { +void RegExpBuiltinsAssembler::StoreLastIndex(TNode<Context> context, + TNode<Object> regexp, + TNode<Number> value, + bool is_fastpath) { if (is_fastpath) { - FastStoreLastIndex(regexp, value); + FastStoreLastIndex(CAST(regexp), CAST(value)); } else { SlowStoreLastIndex(context, regexp, value); } @@ -248,10 +252,10 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( TNode<Context> native_context = LoadNativeContext(context); TNode<Map> map = CAST(LoadContextElement( native_context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP)); - TNode<NameDictionary> properties = AllocateNameDictionary(num_properties); + TNode<NameDictionary> properties = + AllocateNameDictionary(num_properties, kAllowLargeObjectAllocation); - TNode<JSObject> group_object = - CAST(AllocateJSObjectFromMap(map, properties)); + TNode<JSObject> group_object = AllocateJSObjectFromMap(map, properties); StoreObjectField(result, JSRegExpResult::kGroupsOffset, group_object); TVARIABLE(IntPtrT, var_i, IntPtrZero()); @@ -534,19 +538,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal( // We expect exactly one result since we force the called regexp to behave // as non-global. TNode<IntPtrT> int_result = ChangeInt32ToIntPtr(result); + GotoIf( + IntPtrEqual(int_result, IntPtrConstant(RegExp::kInternalRegExpSuccess)), + &if_success); + GotoIf( + IntPtrEqual(int_result, IntPtrConstant(RegExp::kInternalRegExpFailure)), + &if_failure); GotoIf(IntPtrEqual(int_result, - IntPtrConstant(NativeRegExpMacroAssembler::SUCCESS)), - &if_success); - GotoIf(IntPtrEqual(int_result, - IntPtrConstant(NativeRegExpMacroAssembler::FAILURE)), - &if_failure); - GotoIf(IntPtrEqual(int_result, - IntPtrConstant(NativeRegExpMacroAssembler::EXCEPTION)), + IntPtrConstant(RegExp::kInternalRegExpException)), &if_exception); - CSA_ASSERT(this, - IntPtrEqual(int_result, - IntPtrConstant(NativeRegExpMacroAssembler::RETRY))); + CSA_ASSERT(this, IntPtrEqual(int_result, + IntPtrConstant(RegExp::kInternalRegExpRetry))); Goto(&runtime); } @@ -755,7 +758,7 @@ RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( GotoIfNot(should_update_last_index, &out); // Update the new last index from {match_indices}. - TNode<Number> new_lastindex = CAST(UnsafeLoadFixedArrayElement( + TNode<Smi> new_lastindex = CAST(UnsafeLoadFixedArrayElement( CAST(match_indices), RegExpMatchInfo::kFirstCaptureIndex + 1)); StoreLastIndex(context, regexp, new_lastindex, is_fastpath); @@ -852,7 +855,7 @@ Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype(Node* const context, // The smi check is required to omit ToLength(lastIndex) calls with possible // user-code execution on the fast path. - Node* const last_index = FastLoadLastIndex(CAST(object)); + TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object)); var_result.Bind(TaggedIsPositiveSmi(last_index)); Goto(&out); @@ -897,7 +900,7 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpWithOriginalExec( BIND(&check_last_index); // The smi check is required to omit ToLength(lastIndex) calls with possible // user-code execution on the fast path. - TNode<Object> last_index = FastLoadLastIndex(object); + TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(object); var_result = TaggedIsPositiveSmi(last_index); Goto(&out); @@ -925,9 +928,9 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExp( // This should only be needed for String.p.(split||matchAll), but we are // conservative here. - GotoIf(IsRegExpSpeciesProtectorCellInvalid(), if_ismodified); + TNode<Context> native_context = LoadNativeContext(context); + GotoIf(IsRegExpSpeciesProtectorCellInvalid(native_context), if_ismodified); - Node* const native_context = LoadNativeContext(context); Node* const regexp_fun = LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX); Node* const initial_map = @@ -954,7 +957,7 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExp( // The smi check is required to omit ToLength(lastIndex) calls with possible // user-code execution on the fast path. - Node* const last_index = FastLoadLastIndex(CAST(object)); + TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object)); Branch(TaggedIsPositiveSmi(last_index), if_isunmodified, if_ismodified); } @@ -1012,7 +1015,7 @@ TF_BUILTIN(RegExpPrototypeExecSlow, RegExpBuiltinsAssembler) { // Fast path stub for ATOM regexps. String matching is done by StringIndexOf, // and {match_info} is updated on success. -// The slow path is implemented in RegExpImpl::AtomExec. +// The slow path is implemented in RegExp::AtomExec. TF_BUILTIN(RegExpExecAtom, RegExpBuiltinsAssembler) { TNode<JSRegExp> regexp = CAST(Parameter(Descriptor::kRegExp)); TNode<String> subject_string = CAST(Parameter(Descriptor::kString)); @@ -1538,7 +1541,8 @@ TNode<Int32T> RegExpBuiltinsAssembler::FastFlagGetter(TNode<JSRegExp> regexp, JSRegExp::Flag flag) { TNode<Smi> flags = CAST(LoadObjectField(regexp, JSRegExp::kFlagsOffset)); TNode<Smi> mask = SmiConstant(flag); - return SmiToInt32(SmiShr(SmiAnd(flags, mask), JSRegExp::FlagShiftBits(flag))); + return SmiToInt32(SmiShr(SmiAnd(flags, mask), base::bits::CountTrailingZeros( + static_cast<int>(flag)))); } // Load through the GetProperty stub. @@ -1807,10 +1811,9 @@ TF_BUILTIN(RegExpPrototypeTestFast, RegExpBuiltinsAssembler) { Return(FalseConstant()); } -Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string, - Node* const index, - Node* const is_unicode, - bool is_fastpath) { +TNode<Number> RegExpBuiltinsAssembler::AdvanceStringIndex( + SloppyTNode<String> string, SloppyTNode<Number> index, + SloppyTNode<BoolT> is_unicode, bool is_fastpath) { CSA_ASSERT(this, IsString(string)); CSA_ASSERT(this, IsNumberNormalized(index)); if (is_fastpath) CSA_ASSERT(this, TaggedIsPositiveSmi(index)); @@ -1818,8 +1821,8 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string, // Default to last_index + 1. // TODO(pwong): Consider using TrySmiAdd for the fast path to reduce generated // code. - Node* const index_plus_one = NumberInc(index); - VARIABLE(var_result, MachineRepresentation::kTagged, index_plus_one); + TNode<Number> index_plus_one = NumberInc(index); + TVARIABLE(Number, var_result, index_plus_one); // Advancing the index has some subtle issues involving the distinction // between Smis and HeapNumbers. There's three cases: @@ -1846,10 +1849,10 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string, BIND(&if_isunicode); { TNode<IntPtrT> const string_length = LoadStringLengthAsWord(string); - TNode<IntPtrT> untagged_plus_one = SmiUntag(index_plus_one); + TNode<IntPtrT> untagged_plus_one = SmiUntag(CAST(index_plus_one)); GotoIfNot(IntPtrLessThan(untagged_plus_one, string_length), &out); - Node* const lead = StringCharCodeAt(string, SmiUntag(index)); + Node* const lead = StringCharCodeAt(string, SmiUntag(CAST(index))); GotoIfNot(Word32Equal(Word32And(lead, Int32Constant(0xFC00)), Int32Constant(0xD800)), &out); @@ -1860,8 +1863,8 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string, &out); // At a surrogate pair, return index + 2. - Node* const index_plus_two = NumberInc(index_plus_one); - var_result.Bind(index_plus_two); + TNode<Number> index_plus_two = NumberInc(index_plus_one); + var_result = index_plus_two; Goto(&out); } @@ -1870,31 +1873,30 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string, return var_result.value(); } -void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, - Node* const regexp, +void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(TNode<Context> context, + TNode<Object> regexp, TNode<String> string, const bool is_fastpath) { if (is_fastpath) CSA_ASSERT(this, IsFastRegExp(context, regexp)); Node* const is_global = - FlagGetter(CAST(context), CAST(regexp), JSRegExp::kGlobal, is_fastpath); + FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); Label if_isglobal(this), if_isnotglobal(this); Branch(is_global, &if_isglobal, &if_isnotglobal); BIND(&if_isnotglobal); { - Node* const result = - is_fastpath - ? RegExpPrototypeExecBody(CAST(context), CAST(regexp), string, true) - : RegExpExec(context, regexp, string); + Node* const result = is_fastpath ? RegExpPrototypeExecBody( + context, CAST(regexp), string, true) + : RegExpExec(context, regexp, string); Return(result); } BIND(&if_isglobal); { - Node* const is_unicode = FlagGetter(CAST(context), CAST(regexp), - JSRegExp::kUnicode, is_fastpath); + Node* const is_unicode = + FlagGetter(context, regexp, JSRegExp::kUnicode, is_fastpath); StoreLastIndex(context, regexp, SmiZero(), is_fastpath); @@ -1935,8 +1937,8 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, // On the fast path, grab the matching string from the raw match index // array. TNode<RegExpMatchInfo> match_indices = - RegExpPrototypeExecBodyWithoutResult(CAST(context), CAST(regexp), - string, &if_didnotmatch, true); + RegExpPrototypeExecBodyWithoutResult(context, CAST(regexp), string, + &if_didnotmatch, true); Label dosubstring(this), donotsubstring(this); Branch(var_atom.value(), &donotsubstring, &dosubstring); @@ -1988,15 +1990,14 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, TNode<Smi> const match_length = LoadStringLengthAsSmi(match); GotoIfNot(SmiEqual(match_length, SmiZero()), &loop); - Node* last_index = - LoadLastIndex(CAST(context), CAST(regexp), is_fastpath); + Node* last_index = LoadLastIndex(context, regexp, is_fastpath); if (is_fastpath) { CSA_ASSERT(this, TaggedIsPositiveSmi(last_index)); } else { last_index = ToLength_Inline(context, last_index); } - Node* const new_last_index = + TNode<Number> new_last_index = AdvanceStringIndex(string, last_index, is_unicode, is_fastpath); if (is_fastpath) { @@ -2017,7 +2018,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, { // Wrap the match in a JSArray. - Node* const result = array.ToJSArray(CAST(context)); + Node* const result = array.ToJSArray(context); Return(result); } } @@ -2034,7 +2035,7 @@ TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) { ThrowIfNotJSReceiver(context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, "RegExp.prototype.@@match"); - Node* const receiver = maybe_receiver; + TNode<JSReceiver> receiver = CAST(maybe_receiver); // Convert {maybe_string} to a String. TNode<String> const string = ToString_Inline(context, maybe_string); @@ -2086,7 +2087,8 @@ void RegExpMatchAllAssembler::Generate(TNode<Context> context, // 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true). - FastStoreLastIndex(var_matcher.value(), FastLoadLastIndex(fast_regexp)); + FastStoreLastIndex(CAST(var_matcher.value()), + FastLoadLastIndex(fast_regexp)); // 9. If flags contains "g", let global be true. // 10. Else, let global be false. @@ -2226,12 +2228,11 @@ TF_BUILTIN(RegExpMatchFast, RegExpBuiltinsAssembler) { } void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast( - Node* const context, Node* const regexp, Node* const string) { + TNode<Context> context, TNode<JSRegExp> regexp, TNode<String> string) { CSA_ASSERT(this, IsFastRegExp(context, regexp)); - CSA_ASSERT(this, IsString(string)); // Grab the initial value of last index. - Node* const previous_last_index = FastLoadLastIndex(CAST(regexp)); + TNode<Smi> previous_last_index = FastLoadLastIndex(regexp); // Ensure last index is 0. FastStoreLastIndex(regexp, SmiZero()); @@ -2239,7 +2240,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast( // Call exec. Label if_didnotmatch(this); TNode<RegExpMatchInfo> match_indices = RegExpPrototypeExecBodyWithoutResult( - CAST(context), CAST(regexp), CAST(string), &if_didnotmatch, true); + context, regexp, string, &if_didnotmatch, true); // Successful match. { @@ -2839,16 +2840,14 @@ TF_BUILTIN(RegExpStringIteratorPrototypeNext, RegExpStringIteratorAssembler) { GotoIfNot(IsEmptyString(match_str), &return_result); // 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex")). - TNode<Smi> this_index = CAST(FastLoadLastIndex(CAST(iterating_regexp))); - CSA_ASSERT(this, TaggedIsSmi(this_index)); + TNode<Smi> this_index = FastLoadLastIndex(CAST(iterating_regexp)); // 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode). - TNode<Smi> next_index = CAST(AdvanceStringIndex( - iterating_string, this_index, HasUnicodeFlag(flags), true)); - CSA_ASSERT(this, TaggedIsSmi(next_index)); + TNode<Smi> next_index = AdvanceStringIndexFast( + iterating_string, this_index, HasUnicodeFlag(flags)); // 3. Perform ? Set(R, "lastIndex", nextIndex, true). - FastStoreLastIndex(iterating_regexp, next_index); + FastStoreLastIndex(CAST(iterating_regexp), next_index); // iii. Return ! CreateIterResultObject(match, false). Goto(&return_result); @@ -2866,8 +2865,8 @@ TF_BUILTIN(RegExpStringIteratorPrototypeNext, RegExpStringIteratorAssembler) { TNode<Number> this_index = ToLength_Inline(context, last_index); // 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode). - TNode<Object> next_index = CAST(AdvanceStringIndex( - iterating_string, this_index, HasUnicodeFlag(flags), false)); + TNode<Number> next_index = AdvanceStringIndex( + iterating_string, this_index, HasUnicodeFlag(flags), false); // 3. Perform ? Set(R, "lastIndex", nextIndex, true). SlowStoreLastIndex(context, iterating_regexp, next_index); diff --git a/deps/v8/src/builtins/builtins-regexp-gen.h b/deps/v8/src/builtins/builtins-regexp-gen.h index 88c00095b9..3677314f19 100644 --- a/deps/v8/src/builtins/builtins-regexp-gen.h +++ b/deps/v8/src/builtins/builtins-regexp-gen.h @@ -7,7 +7,7 @@ #include "src/base/optional.h" #include "src/codegen/code-stub-assembler.h" -#include "src/execution/message-template.h" +#include "src/common/message-template.h" namespace v8 { namespace internal { @@ -42,15 +42,20 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { TNode<Context> context, TNode<Smi> length, TNode<Smi> index, TNode<String> input, TNode<FixedArray>* elements_out = nullptr); - TNode<Object> FastLoadLastIndex(TNode<JSRegExp> regexp); + TNode<Object> FastLoadLastIndexBeforeSmiCheck(TNode<JSRegExp> regexp); + TNode<Smi> FastLoadLastIndex(TNode<JSRegExp> regexp) { + return CAST(FastLoadLastIndexBeforeSmiCheck(regexp)); + } TNode<Object> SlowLoadLastIndex(TNode<Context> context, TNode<Object> regexp); TNode<Object> LoadLastIndex(TNode<Context> context, TNode<Object> regexp, bool is_fastpath); - void FastStoreLastIndex(Node* regexp, Node* value); - void SlowStoreLastIndex(Node* context, Node* regexp, Node* value); - void StoreLastIndex(Node* context, Node* regexp, Node* value, - bool is_fastpath); + void FastStoreLastIndex(TNode<JSRegExp> regexp, TNode<Smi> value); + void SlowStoreLastIndex(SloppyTNode<Context> context, + SloppyTNode<Object> regexp, + SloppyTNode<Number> value); + void StoreLastIndex(TNode<Context> context, TNode<Object> regexp, + TNode<Number> value, bool is_fastpath); // Loads {var_string_start} and {var_string_end} with the corresponding // offsets into the given {string_data}. @@ -127,20 +132,23 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { Node* RegExpExec(Node* context, Node* regexp, Node* string); - Node* AdvanceStringIndex(Node* const string, Node* const index, - Node* const is_unicode, bool is_fastpath); + TNode<Number> AdvanceStringIndex(SloppyTNode<String> string, + SloppyTNode<Number> index, + SloppyTNode<BoolT> is_unicode, + bool is_fastpath); - Node* AdvanceStringIndexFast(Node* const string, Node* const index, - Node* const is_unicode) { - return AdvanceStringIndex(string, index, is_unicode, true); + TNode<Smi> AdvanceStringIndexFast(TNode<String> string, TNode<Smi> index, + TNode<BoolT> is_unicode) { + return CAST(AdvanceStringIndex(string, index, is_unicode, true)); } - void RegExpPrototypeMatchBody(Node* const context, Node* const regexp, + void RegExpPrototypeMatchBody(TNode<Context> context, TNode<Object> regexp, TNode<String> const string, const bool is_fastpath); - void RegExpPrototypeSearchBodyFast(Node* const context, Node* const regexp, - Node* const string); + void RegExpPrototypeSearchBodyFast(TNode<Context> context, + TNode<JSRegExp> regexp, + TNode<String> string); void RegExpPrototypeSearchBodySlow(Node* const context, Node* const regexp, Node* const string); diff --git a/deps/v8/src/builtins/builtins-regexp.cc b/deps/v8/src/builtins/builtins-regexp.cc index 3e0f7182c7..e758782a99 100644 --- a/deps/v8/src/builtins/builtins-regexp.cc +++ b/deps/v8/src/builtins/builtins-regexp.cc @@ -6,8 +6,8 @@ #include "src/builtins/builtins.h" #include "src/logging/counters.h" #include "src/objects/objects-inl.h" -#include "src/regexp/jsregexp.h" #include "src/regexp/regexp-utils.h" +#include "src/regexp/regexp.h" #include "src/strings/string-builder-inl.h" namespace v8 { diff --git a/deps/v8/src/builtins/builtins-string-gen.cc b/deps/v8/src/builtins/builtins-string-gen.cc index 5689b42619..97dc8ca895 100644 --- a/deps/v8/src/builtins/builtins-string-gen.cc +++ b/deps/v8/src/builtins/builtins-string-gen.cc @@ -545,32 +545,33 @@ TF_BUILTIN(StringCharAt, StringBuiltinsAssembler) { Return(result); } -TF_BUILTIN(StringCodePointAtUTF16, StringBuiltinsAssembler) { +TF_BUILTIN(StringCodePointAt, StringBuiltinsAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); Node* position = Parameter(Descriptor::kPosition); + // TODO(sigurds) Figure out if passing length as argument pays off. TNode<IntPtrT> length = LoadStringLengthAsWord(receiver); // Load the character code at the {position} from the {receiver}. TNode<Int32T> code = - LoadSurrogatePairAt(receiver, length, position, UnicodeEncoding::UTF16); + LoadSurrogatePairAt(receiver, length, position, UnicodeEncoding::UTF32); // And return it as TaggedSigned value. // TODO(turbofan): Allow builtins to return values untagged. TNode<Smi> result = SmiFromInt32(code); Return(result); } -TF_BUILTIN(StringCodePointAtUTF32, StringBuiltinsAssembler) { - Node* receiver = Parameter(Descriptor::kReceiver); - Node* position = Parameter(Descriptor::kPosition); +TF_BUILTIN(StringFromCodePointAt, StringBuiltinsAssembler) { + TNode<String> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<IntPtrT> position = + UncheckedCast<IntPtrT>(Parameter(Descriptor::kPosition)); // TODO(sigurds) Figure out if passing length as argument pays off. TNode<IntPtrT> length = LoadStringLengthAsWord(receiver); // Load the character code at the {position} from the {receiver}. TNode<Int32T> code = - LoadSurrogatePairAt(receiver, length, position, UnicodeEncoding::UTF32); - // And return it as TaggedSigned value. - // TODO(turbofan): Allow builtins to return values untagged. - TNode<Smi> result = SmiFromInt32(code); + LoadSurrogatePairAt(receiver, length, position, UnicodeEncoding::UTF16); + // Create a String from the UTF16 encoded code point + TNode<String> result = StringFromSingleUTF16EncodedCodePoint(code); Return(result); } @@ -952,19 +953,6 @@ void StringIncludesIndexOfAssembler::Generate(SearchVariant variant, } } -void StringBuiltinsAssembler::RequireObjectCoercible(Node* const context, - Node* const value, - const char* method_name) { - Label out(this), throw_exception(this, Label::kDeferred); - Branch(IsNullOrUndefined(value), &throw_exception, &out); - - BIND(&throw_exception); - ThrowTypeError(context, MessageTemplate::kCalledOnNullOrUndefined, - method_name); - - BIND(&out); -} - void StringBuiltinsAssembler::MaybeCallFunctionAtSymbol( Node* const context, Node* const object, Node* const maybe_string, Handle<Symbol> symbol, DescriptorIndexAndName symbol_index, @@ -1072,10 +1060,10 @@ compiler::Node* StringBuiltinsAssembler::GetSubstitution( TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) { Label out(this); - Node* const receiver = Parameter(Descriptor::kReceiver); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Node* const search = Parameter(Descriptor::kSearch); Node* const replace = Parameter(Descriptor::kReplace); - Node* const context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Smi> const smi_zero = SmiConstant(0); @@ -1578,7 +1566,7 @@ TF_BUILTIN(StringPrototypeSplit, StringBuiltinsAssembler) { ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)); CodeStubArguments args(this, argc); - Node* const receiver = args.GetReceiver(); + TNode<Object> receiver = args.GetReceiver(); Node* const separator = args.GetOptionalArgumentValue(kSeparatorArg); Node* const limit = args.GetOptionalArgumentValue(kLimitArg); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -1986,12 +1974,12 @@ TNode<Int32T> StringBuiltinsAssembler::LoadSurrogatePairAt( switch (encoding) { case UnicodeEncoding::UTF16: - var_result = Signed(Word32Or( + var_result = Word32Or( // Need to swap the order for big-endian platforms #if V8_TARGET_BIG_ENDIAN - Word32Shl(lead, Int32Constant(16)), trail)); + Word32Shl(lead, Int32Constant(16)), trail); #else - Word32Shl(trail, Int32Constant(16)), lead)); + Word32Shl(trail, Int32Constant(16)), lead); #endif break; @@ -2002,8 +1990,8 @@ TNode<Int32T> StringBuiltinsAssembler::LoadSurrogatePairAt( Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00); // (lead << 10) + trail + SURROGATE_OFFSET - var_result = Signed(Int32Add(Word32Shl(lead, Int32Constant(10)), - Int32Add(trail, surrogate_offset))); + var_result = Int32Add(Word32Shl(lead, Int32Constant(10)), + Int32Add(trail, surrogate_offset)); break; } } diff --git a/deps/v8/src/builtins/builtins-string-gen.h b/deps/v8/src/builtins/builtins-string-gen.h index 92ebd3803b..679ce0e17f 100644 --- a/deps/v8/src/builtins/builtins-string-gen.h +++ b/deps/v8/src/builtins/builtins-string-gen.h @@ -76,9 +76,6 @@ class StringBuiltinsAssembler : public CodeStubAssembler { TNode<Smi> subject_length, TNode<Number> limit_number); - void RequireObjectCoercible(Node* const context, Node* const value, - const char* method_name); - TNode<BoolT> SmiIsNegative(TNode<Smi> value) { return SmiLessThan(value, SmiConstant(0)); } diff --git a/deps/v8/src/builtins/builtins-symbol-gen.cc b/deps/v8/src/builtins/builtins-symbol-gen.cc index 4e8c9f9850..610a8baeb3 100644 --- a/deps/v8/src/builtins/builtins-symbol-gen.cc +++ b/deps/v8/src/builtins/builtins-symbol-gen.cc @@ -13,8 +13,8 @@ namespace internal { // ES #sec-symbol-objects // ES #sec-symbol.prototype.description TF_BUILTIN(SymbolPrototypeDescriptionGetter, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Node* value = ToThisValue(context, receiver, PrimitiveType::kSymbol, "Symbol.prototype.description"); @@ -24,8 +24,8 @@ TF_BUILTIN(SymbolPrototypeDescriptionGetter, CodeStubAssembler) { // ES6 #sec-symbol.prototype-@@toprimitive TF_BUILTIN(SymbolPrototypeToPrimitive, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Node* result = ToThisValue(context, receiver, PrimitiveType::kSymbol, "Symbol.prototype [ @@toPrimitive ]"); @@ -34,8 +34,8 @@ TF_BUILTIN(SymbolPrototypeToPrimitive, CodeStubAssembler) { // ES6 #sec-symbol.prototype.tostring TF_BUILTIN(SymbolPrototypeToString, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Node* value = ToThisValue(context, receiver, PrimitiveType::kSymbol, "Symbol.prototype.toString"); @@ -45,8 +45,8 @@ TF_BUILTIN(SymbolPrototypeToString, CodeStubAssembler) { // ES6 #sec-symbol.prototype.valueof TF_BUILTIN(SymbolPrototypeValueOf, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Node* result = ToThisValue(context, receiver, PrimitiveType::kSymbol, "Symbol.prototype.valueOf"); diff --git a/deps/v8/src/builtins/builtins-typed-array-gen.cc b/deps/v8/src/builtins/builtins-typed-array-gen.cc index 8484685a6a..857d33988f 100644 --- a/deps/v8/src/builtins/builtins-typed-array-gen.cc +++ b/deps/v8/src/builtins/builtins-typed-array-gen.cc @@ -18,32 +18,12 @@ using compiler::Node; template <class T> using TNode = compiler::TNode<T>; -// This is needed for gc_mole which will compile this file without the full set -// of GN defined macros. -#ifndef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP -#define V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP 64 -#endif - // ----------------------------------------------------------------------------- // ES6 section 22.2 TypedArray Objects -// Setup the TypedArray which is under construction. -// - Set the length. -// - Set the byte_offset. -// - Set the byte_length. -// - Set EmbedderFields to 0. -void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder, - TNode<UintPtrT> length, - TNode<UintPtrT> byte_offset, - TNode<UintPtrT> byte_length) { - StoreObjectFieldNoWriteBarrier(holder, JSTypedArray::kLengthOffset, length, - MachineType::PointerRepresentation()); - StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset, - byte_offset, - MachineType::PointerRepresentation()); - StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteLengthOffset, - byte_length, - MachineType::PointerRepresentation()); +// Sets the embedder fields to 0 for a TypedArray which is under construction. +void TypedArrayBuiltinsAssembler::SetupTypedArrayEmbedderFields( + TNode<JSTypedArray> holder) { for (int offset = JSTypedArray::kHeaderSize; offset < JSTypedArray::kSizeWithEmbedderFields; offset += kTaggedSize) { StoreObjectField(holder, offset, SmiConstant(0)); @@ -54,8 +34,7 @@ void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder, // elements. // TODO(bmeurer,v8:4153): Rename this and maybe fix up the implementation a bit. TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer( - TNode<Context> context, TNode<JSTypedArray> holder, - TNode<UintPtrT> byte_length) { + TNode<Context> context, TNode<UintPtrT> byte_length) { TNode<Context> native_context = LoadNativeContext(context); TNode<Map> map = CAST(LoadContextElement(native_context, Context::ARRAY_BUFFER_MAP_INDEX)); @@ -97,16 +76,6 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer( offset < JSArrayBuffer::kSizeWithEmbedderFields; offset += kTaggedSize) { StoreObjectFieldNoWriteBarrier(buffer, offset, SmiConstant(0)); } - - StoreObjectField(holder, JSTypedArray::kBufferOffset, buffer); - - TNode<ByteArray> elements = AllocateByteArray(byte_length); - StoreObjectField(holder, JSTypedArray::kElementsOffset, elements); - StoreObjectField(holder, JSTypedArray::kBasePointerOffset, elements); - StoreObjectFieldNoWriteBarrier( - holder, JSTypedArray::kExternalPointerOffset, - PointerConstant(JSTypedArray::ExternalPointerForOnHeapArray()), - MachineType::PointerRepresentation()); return buffer; } @@ -200,13 +169,13 @@ TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) { Return(ChangeUintPtrToTagged(length)); } -TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind( +TNode<BoolT> TypedArrayBuiltinsAssembler::IsUint8ElementsKind( TNode<Word32T> kind) { return Word32Or(Word32Equal(kind, Int32Constant(UINT8_ELEMENTS)), Word32Equal(kind, Int32Constant(UINT8_CLAMPED_ELEMENTS))); } -TNode<Word32T> TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind( +TNode<BoolT> TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind( TNode<Word32T> kind) { return Word32Or(Word32Equal(kind, Int32Constant(BIGINT64_ELEMENTS)), Word32Equal(kind, Int32Constant(BIGUINT64_ELEMENTS))); @@ -228,7 +197,12 @@ TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize( TorqueStructTypedArrayElementsInfo TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo( TNode<JSTypedArray> typed_array) { - TNode<Int32T> elements_kind = LoadElementsKind(typed_array); + return GetTypedArrayElementsInfo(LoadMap(typed_array)); +} + +TorqueStructTypedArrayElementsInfo +TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(TNode<Map> map) { + TNode<Int32T> elements_kind = LoadMapElementsKind(map); TVARIABLE(UintPtrT, var_size_log2); TVARIABLE(Map, var_map); ReadOnlyRoots roots(isolate()); @@ -294,10 +268,9 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::GetBuffer( Label call_runtime(this), done(this); TVARIABLE(Object, var_result); - TNode<Object> buffer = LoadObjectField(array, JSTypedArray::kBufferOffset); + TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(array); GotoIf(IsDetachedBuffer(buffer), &call_runtime); - TNode<UintPtrT> backing_store = LoadObjectField<UintPtrT>( - CAST(buffer), JSArrayBuffer::kBackingStoreOffset); + TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStore(buffer); GotoIf(WordEqual(backing_store, IntPtrConstant(0)), &call_runtime); var_result = buffer; Goto(&done); @@ -327,10 +300,10 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource( TNode<Context> context, TNode<JSTypedArray> source, TNode<JSTypedArray> target, TNode<IntPtrT> offset, Label* call_runtime, Label* if_source_too_large) { - CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer( - LoadObjectField(source, JSTypedArray::kBufferOffset)))); - CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer( - LoadObjectField(target, JSTypedArray::kBufferOffset)))); + CSA_ASSERT(this, Word32BinaryNot( + IsDetachedBuffer(LoadJSArrayBufferViewBuffer(source)))); + CSA_ASSERT(this, Word32BinaryNot( + IsDetachedBuffer(LoadJSArrayBufferViewBuffer(target)))); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(offset, IntPtrConstant(0))); CSA_ASSERT(this, IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue))); @@ -774,8 +747,8 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) { // ToNumber/ToBigInt may execute JavaScript code, which could // detach the array's buffer. - Node* buffer = - LoadObjectField(new_typed_array, JSTypedArray::kBufferOffset); + TNode<JSArrayBuffer> buffer = + LoadJSArrayBufferViewBuffer(new_typed_array); GotoIf(IsDetachedBuffer(buffer), &if_detached); // GC may move backing store in ToNumber, thus load backing @@ -997,8 +970,8 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { // ToNumber/ToBigInt may execute JavaScript code, which could // detach the array's buffer. - Node* buffer = LoadObjectField(target_obj.value(), - JSTypedArray::kBufferOffset); + TNode<JSArrayBuffer> buffer = + LoadJSArrayBufferViewBuffer(target_obj.value()); GotoIf(IsDetachedBuffer(buffer), &if_detached); // GC may move backing store in map_fn, thus load backing @@ -1027,7 +1000,5 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { "%TypedArray%.from"); } -#undef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/builtins-typed-array-gen.h b/deps/v8/src/builtins/builtins-typed-array-gen.h index 6fb02a657c..d637bc9c6b 100644 --- a/deps/v8/src/builtins/builtins-typed-array-gen.h +++ b/deps/v8/src/builtins/builtins-typed-array-gen.h @@ -27,15 +27,12 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler { const char* method_name, IterationKind iteration_kind); - void SetupTypedArray(TNode<JSTypedArray> holder, TNode<UintPtrT> length, - TNode<UintPtrT> byte_offset, - TNode<UintPtrT> byte_length); + void SetupTypedArrayEmbedderFields(TNode<JSTypedArray> holder); void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer, TNode<Map> map, TNode<Smi> length, TNode<UintPtrT> byte_offset); TNode<JSArrayBuffer> AllocateEmptyOnHeapBuffer(TNode<Context> context, - TNode<JSTypedArray> holder, TNode<UintPtrT> byte_length); TNode<Map> LoadMapForType(TNode<JSTypedArray> array); @@ -44,16 +41,17 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler { TNode<UintPtrT> byte_offset); // Returns true if kind is either UINT8_ELEMENTS or UINT8_CLAMPED_ELEMENTS. - TNode<Word32T> IsUint8ElementsKind(TNode<Word32T> kind); + TNode<BoolT> IsUint8ElementsKind(TNode<Word32T> kind); // Returns true if kind is either BIGINT64_ELEMENTS or BIGUINT64_ELEMENTS. - TNode<Word32T> IsBigInt64ElementsKind(TNode<Word32T> kind); + TNode<BoolT> IsBigInt64ElementsKind(TNode<Word32T> kind); // Returns the byte size of an element for a TypedArray elements kind. TNode<IntPtrT> GetTypedArrayElementSize(TNode<Word32T> elements_kind); // Returns information (byte size and map) about a TypedArray's elements. ElementsInfo GetTypedArrayElementsInfo(TNode<JSTypedArray> typed_array); + ElementsInfo GetTypedArrayElementsInfo(TNode<Map> map); TNode<JSFunction> GetDefaultConstructor(TNode<Context> context, TNode<JSTypedArray> exemplar); diff --git a/deps/v8/src/builtins/builtins-weak-refs.cc b/deps/v8/src/builtins/builtins-weak-refs.cc index 78f37c0cf5..18738d2c48 100644 --- a/deps/v8/src/builtins/builtins-weak-refs.cc +++ b/deps/v8/src/builtins/builtins-weak-refs.cc @@ -48,14 +48,24 @@ BUILTIN(FinalizationGroupRegister) { HandleScope scope(isolate); const char* method_name = "FinalizationGroup.prototype.register"; + // 1. Let finalizationGroup be the this value. + // + // 2. If Type(finalizationGroup) is not Object, throw a TypeError + // exception. + // + // 4. If finalizationGroup does not have a [[Cells]] internal slot, + // throw a TypeError exception. CHECK_RECEIVER(JSFinalizationGroup, finalization_group, method_name); Handle<Object> target = args.atOrUndefined(isolate, 1); + + // 3. If Type(target) is not Object, throw a TypeError exception. if (!target->IsJSReceiver()) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kWeakRefsRegisterTargetMustBeObject)); } + Handle<Object> holdings = args.atOrUndefined(isolate, 2); if (target->SameValue(*holdings)) { THROW_NEW_ERROR_RETURN_FAILURE( @@ -64,15 +74,21 @@ BUILTIN(FinalizationGroupRegister) { MessageTemplate::kWeakRefsRegisterTargetAndHoldingsMustNotBeSame)); } - Handle<Object> key = args.atOrUndefined(isolate, 3); - // TODO(marja, gsathya): Restrictions on "key" (e.g., does it need to be an - // object). + Handle<Object> unregister_token = args.atOrUndefined(isolate, 3); + // 5. If Type(unregisterToken) is not Object, + // a. If unregisterToken is not undefined, throw a TypeError exception. + if (!unregister_token->IsJSReceiver() && !unregister_token->IsUndefined()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kWeakRefsUnregisterTokenMustBeObject, + unregister_token)); + } // TODO(marja): Realms. JSFinalizationGroup::Register(finalization_group, - Handle<JSReceiver>::cast(target), holdings, key, - isolate); + Handle<JSReceiver>::cast(target), holdings, + unregister_token, isolate); return ReadOnlyRoots(isolate).undefined_value(); } @@ -80,25 +96,63 @@ BUILTIN(FinalizationGroupUnregister) { HandleScope scope(isolate); const char* method_name = "FinalizationGroup.prototype.unregister"; + // 1. Let finalizationGroup be the this value. + // + // 2. If Type(finalizationGroup) is not Object, throw a TypeError + // exception. + // + // 3. If finalizationGroup does not have a [[Cells]] internal slot, + // throw a TypeError exception. CHECK_RECEIVER(JSFinalizationGroup, finalization_group, method_name); - Handle<Object> key = args.atOrUndefined(isolate, 1); - JSFinalizationGroup::Unregister(finalization_group, key, isolate); - return ReadOnlyRoots(isolate).undefined_value(); + Handle<Object> unregister_token = args.atOrUndefined(isolate, 1); + + // 4. If Type(unregisterToken) is not Object, throw a TypeError exception. + if (!unregister_token->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kWeakRefsUnregisterTokenMustBeObject, + unregister_token)); + } + + bool success = JSFinalizationGroup::Unregister( + finalization_group, Handle<JSReceiver>::cast(unregister_token), isolate); + + return *isolate->factory()->ToBoolean(success); } BUILTIN(FinalizationGroupCleanupSome) { HandleScope scope(isolate); const char* method_name = "FinalizationGroup.prototype.cleanupSome"; + // 1. Let finalizationGroup be the this value. + // + // 2. If Type(finalizationGroup) is not Object, throw a TypeError + // exception. + // + // 3. If finalizationGroup does not have a [[Cells]] internal slot, + // throw a TypeError exception. CHECK_RECEIVER(JSFinalizationGroup, finalization_group, method_name); - // TODO(marja, gsathya): Add missing "cleanup" callback. + Handle<Object> callback(finalization_group->cleanup(), isolate); + Handle<Object> callback_obj = args.atOrUndefined(isolate, 1); + + // 4. If callback is not undefined and IsCallable(callback) is + // false, throw a TypeError exception. + if (!callback_obj->IsUndefined(isolate)) { + if (!callback_obj->IsCallable()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kWeakRefsCleanupMustBeCallable)); + } + callback = callback_obj; + } // Don't do set_scheduled_for_cleanup(false); we still have the microtask // scheduled and don't want to schedule another one in case the user never // executes microtasks. - JSFinalizationGroup::Cleanup(finalization_group, isolate); + JSFinalizationGroup::Cleanup(isolate, finalization_group, callback); + return ReadOnlyRoots(isolate).undefined_value(); } @@ -138,7 +192,7 @@ BUILTIN(WeakRefConstructor) { } Handle<JSReceiver> target_receiver = handle(JSReceiver::cast(*target_object), isolate); - isolate->heap()->AddKeepDuringJobTarget(target_receiver); + isolate->heap()->KeepDuringJob(target_receiver); // TODO(marja): Realms. @@ -158,9 +212,9 @@ BUILTIN(WeakRefDeref) { if (weak_ref->target().IsJSReceiver()) { Handle<JSReceiver> target = handle(JSReceiver::cast(weak_ref->target()), isolate); - // AddKeepDuringJobTarget might allocate and cause a GC, but it won't clear + // KeepDuringJob might allocate and cause a GC, but it won't clear // weak_ref since we hold a Handle to its target. - isolate->heap()->AddKeepDuringJobTarget(target); + isolate->heap()->KeepDuringJob(target); } else { DCHECK(weak_ref->target().IsUndefined(isolate)); } diff --git a/deps/v8/src/builtins/collections.tq b/deps/v8/src/builtins/collections.tq index eb95a77023..b83906d109 100644 --- a/deps/v8/src/builtins/collections.tq +++ b/deps/v8/src/builtins/collections.tq @@ -33,7 +33,7 @@ namespace collections { } } } - case (receiver: JSReceiver): { + case (JSReceiver): { goto MayHaveSideEffects; } case (o: Object): deferred { diff --git a/deps/v8/src/builtins/data-view.tq b/deps/v8/src/builtins/data-view.tq index 842e9527ee..62a0cc31c3 100644 --- a/deps/v8/src/builtins/data-view.tq +++ b/deps/v8/src/builtins/data-view.tq @@ -74,16 +74,17 @@ namespace data_view { // ES6 section 24.2.4.1 get DataView.prototype.buffer javascript builtin DataViewPrototypeGetBuffer( - context: Context, receiver: Object, ...arguments): JSArrayBuffer { - let dataView: JSDataView = + js-implicit context: Context, + receiver: Object)(...arguments): JSArrayBuffer { + const dataView: JSDataView = ValidateDataView(context, receiver, 'get DataView.prototype.buffer'); return dataView.buffer; } // ES6 section 24.2.4.2 get DataView.prototype.byteLength javascript builtin DataViewPrototypeGetByteLength( - context: Context, receiver: Object, ...arguments): Number { - let dataView: JSDataView = ValidateDataView( + js-implicit context: Context, receiver: Object)(...arguments): Number { + const dataView: JSDataView = ValidateDataView( context, receiver, 'get DataView.prototype.byte_length'); if (WasNeutered(dataView)) { // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError @@ -95,8 +96,8 @@ namespace data_view { // ES6 section 24.2.4.3 get DataView.prototype.byteOffset javascript builtin DataViewPrototypeGetByteOffset( - context: Context, receiver: Object, ...arguments): Number { - let dataView: JSDataView = ValidateDataView( + js-implicit context: Context, receiver: Object)(...arguments): Number { + const dataView: JSDataView = ValidateDataView( context, receiver, 'get DataView.prototype.byte_offset'); if (WasNeutered(dataView)) { // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError @@ -128,7 +129,7 @@ namespace data_view { macro LoadDataView16( buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool, signed: constexpr bool): Number { - let dataPointer: RawPtr = buffer.backing_store; + const dataPointer: RawPtr = buffer.backing_store; let b0: int32; let b1: int32; @@ -155,12 +156,12 @@ namespace data_view { macro LoadDataView32( buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool, kind: constexpr ElementsKind): Number { - let dataPointer: RawPtr = buffer.backing_store; + const dataPointer: RawPtr = buffer.backing_store; - let b0: uint32 = LoadUint8(dataPointer, offset); - let b1: uint32 = LoadUint8(dataPointer, offset + 1); - let b2: uint32 = LoadUint8(dataPointer, offset + 2); - let b3: uint32 = LoadUint8(dataPointer, offset + 3); + const b0: uint32 = LoadUint8(dataPointer, offset); + const b1: uint32 = LoadUint8(dataPointer, offset + 1); + const b2: uint32 = LoadUint8(dataPointer, offset + 2); + const b3: uint32 = LoadUint8(dataPointer, offset + 3); let result: uint32; if (requestedLittleEndian) { @@ -174,7 +175,7 @@ namespace data_view { } else if constexpr (kind == UINT32_ELEMENTS) { return Convert<Number>(result); } else if constexpr (kind == FLOAT32_ELEMENTS) { - let floatRes: float64 = Convert<float64>(BitcastInt32ToFloat32(result)); + const floatRes: float64 = Convert<float64>(BitcastInt32ToFloat32(result)); return Convert<Number>(floatRes); } else { unreachable; @@ -184,16 +185,16 @@ namespace data_view { macro LoadDataViewFloat64( buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool): Number { - let dataPointer: RawPtr = buffer.backing_store; - - let b0: uint32 = LoadUint8(dataPointer, offset); - let b1: uint32 = LoadUint8(dataPointer, offset + 1); - let b2: uint32 = LoadUint8(dataPointer, offset + 2); - let b3: uint32 = LoadUint8(dataPointer, offset + 3); - let b4: uint32 = LoadUint8(dataPointer, offset + 4); - let b5: uint32 = LoadUint8(dataPointer, offset + 5); - let b6: uint32 = LoadUint8(dataPointer, offset + 6); - let b7: uint32 = LoadUint8(dataPointer, offset + 7); + const dataPointer: RawPtr = buffer.backing_store; + + const b0: uint32 = LoadUint8(dataPointer, offset); + const b1: uint32 = LoadUint8(dataPointer, offset + 1); + const b2: uint32 = LoadUint8(dataPointer, offset + 2); + const b3: uint32 = LoadUint8(dataPointer, offset + 3); + const b4: uint32 = LoadUint8(dataPointer, offset + 4); + const b5: uint32 = LoadUint8(dataPointer, offset + 5); + const b6: uint32 = LoadUint8(dataPointer, offset + 6); + const b7: uint32 = LoadUint8(dataPointer, offset + 7); let lowWord: uint32; let highWord: uint32; @@ -212,74 +213,49 @@ namespace data_view { return Convert<Number>(result); } - extern macro AllocateBigInt(intptr): BigInt; - extern macro StoreBigIntBitfield(BigInt, uint32): void; - extern macro StoreBigIntDigit(BigInt, constexpr int31, uintptr): void; - extern macro DataViewBuiltinsAssembler::DataViewEncodeBigIntBits( - constexpr bool, constexpr int31): uint32; - - const kPositiveBigInt: constexpr bool = false; - const kNegativeBigInt: constexpr bool = true; const kZeroDigitBigInt: constexpr int31 = 0; const kOneDigitBigInt: constexpr int31 = 1; const kTwoDigitBigInt: constexpr int31 = 2; - macro CreateEmptyBigInt(isPositive: bool, length: constexpr int31): BigInt { - // Allocate a BigInt with the desired length (number of digits). - let result: BigInt = AllocateBigInt(length); - - // Write the desired sign and length to the BigInt bitfield. - if (isPositive) { - StoreBigIntBitfield( - result, DataViewEncodeBigIntBits(kPositiveBigInt, length)); - } else { - StoreBigIntBitfield( - result, DataViewEncodeBigIntBits(kNegativeBigInt, length)); - } - - return result; - } - // Create a BigInt on a 64-bit architecture from two 32-bit values. - macro MakeBigIntOn64Bit( + macro MakeBigIntOn64Bit(implicit context: Context)( lowWord: uint32, highWord: uint32, signed: constexpr bool): BigInt { // 0n is represented by a zero-length BigInt. if (lowWord == 0 && highWord == 0) { - return AllocateBigInt(kZeroDigitBigInt); + return Convert<BigInt>(bigint::AllocateBigInt(kZeroDigitBigInt)); } - let isPositive: bool = true; - let highPart: intptr = Signed(Convert<uintptr>(highWord)); - let lowPart: intptr = Signed(Convert<uintptr>(lowWord)); + let sign: uint32 = bigint::kPositiveSign; + const highPart: intptr = Signed(Convert<uintptr>(highWord)); + const lowPart: intptr = Signed(Convert<uintptr>(lowWord)); let rawValue: intptr = (highPart << 32) + lowPart; if constexpr (signed) { if (rawValue < 0) { - isPositive = false; + sign = bigint::kNegativeSign; // We have to store the absolute value of rawValue in the digit. rawValue = 0 - rawValue; } } // Allocate the BigInt and store the absolute value. - let result: BigInt = CreateEmptyBigInt(isPositive, kOneDigitBigInt); - - StoreBigIntDigit(result, 0, Unsigned(rawValue)); - - return result; + const result: MutableBigInt = + bigint::AllocateEmptyBigInt(sign, kOneDigitBigInt); + bigint::StoreBigIntDigit(result, 0, Unsigned(rawValue)); + return Convert<BigInt>(result); } // Create a BigInt on a 32-bit architecture from two 32-bit values. - macro MakeBigIntOn32Bit( + macro MakeBigIntOn32Bit(implicit context: Context)( lowWord: uint32, highWord: uint32, signed: constexpr bool): BigInt { // 0n is represented by a zero-length BigInt. if (lowWord == 0 && highWord == 0) { - return AllocateBigInt(kZeroDigitBigInt); + return Convert<BigInt>(bigint::AllocateBigInt(kZeroDigitBigInt)); } // On a 32-bit platform, we might need 1 or 2 digits to store the number. let needTwoDigits: bool = false; - let isPositive: bool = true; + let sign: uint32 = bigint::kPositiveSign; // We need to do some math on lowWord and highWord, // so Convert them to int32. @@ -293,7 +269,7 @@ namespace data_view { if constexpr (signed) { // If highPart < 0, the number is always negative. if (highPart < 0) { - isPositive = false; + sign = bigint::kNegativeSign; // We have to compute the absolute value by hand. // There will be a negative carry from the low word @@ -322,25 +298,23 @@ namespace data_view { } // Allocate the BigInt with the right sign and length. - let result: BigInt; + let result: MutableBigInt; if (needTwoDigits) { - result = CreateEmptyBigInt(isPositive, kTwoDigitBigInt); + result = bigint::AllocateEmptyBigInt(sign, kTwoDigitBigInt); } else { - result = CreateEmptyBigInt(isPositive, kOneDigitBigInt); + result = bigint::AllocateEmptyBigInt(sign, kOneDigitBigInt); } // Finally, write the digit(s) to the BigInt. - StoreBigIntDigit(result, 0, Unsigned(Convert<intptr>(lowPart))); - + bigint::StoreBigIntDigit(result, 0, Unsigned(Convert<intptr>(lowPart))); if (needTwoDigits) { - StoreBigIntDigit(result, 1, Unsigned(Convert<intptr>(highPart))); + bigint::StoreBigIntDigit(result, 1, Unsigned(Convert<intptr>(highPart))); } - - return result; + return Convert<BigInt>(result); } - macro MakeBigInt(lowWord: uint32, highWord: uint32, signed: constexpr bool): - BigInt { + macro MakeBigInt(implicit context: Context)( + lowWord: uint32, highWord: uint32, signed: constexpr bool): BigInt { // A BigInt digit has the platform word size, so we only need one digit // on 64-bit platforms but may need two on 32-bit. if constexpr (Is64()) { @@ -350,19 +324,19 @@ namespace data_view { } } - macro LoadDataViewBigInt( + macro LoadDataViewBigInt(implicit context: Context)( buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool, signed: constexpr bool): BigInt { - let dataPointer: RawPtr = buffer.backing_store; - - let b0: uint32 = LoadUint8(dataPointer, offset); - let b1: uint32 = LoadUint8(dataPointer, offset + 1); - let b2: uint32 = LoadUint8(dataPointer, offset + 2); - let b3: uint32 = LoadUint8(dataPointer, offset + 3); - let b4: uint32 = LoadUint8(dataPointer, offset + 4); - let b5: uint32 = LoadUint8(dataPointer, offset + 5); - let b6: uint32 = LoadUint8(dataPointer, offset + 6); - let b7: uint32 = LoadUint8(dataPointer, offset + 7); + const dataPointer: RawPtr = buffer.backing_store; + + const b0: uint32 = LoadUint8(dataPointer, offset); + const b1: uint32 = LoadUint8(dataPointer, offset + 1); + const b2: uint32 = LoadUint8(dataPointer, offset + 2); + const b3: uint32 = LoadUint8(dataPointer, offset + 3); + const b4: uint32 = LoadUint8(dataPointer, offset + 4); + const b5: uint32 = LoadUint8(dataPointer, offset + 5); + const b6: uint32 = LoadUint8(dataPointer, offset + 6); + const b7: uint32 = LoadUint8(dataPointer, offset + 7); let lowWord: uint32; let highWord: uint32; @@ -385,7 +359,7 @@ namespace data_view { transitioning macro DataViewGet( context: Context, receiver: Object, offset: Object, requestedLittleEndian: Object, kind: constexpr ElementsKind): Numeric { - let dataView: JSDataView = + const dataView: JSDataView = ValidateDataView(context, receiver, MakeDataViewGetterNameString(kind)); let getIndex: Number; @@ -396,25 +370,25 @@ namespace data_view { ThrowRangeError(kInvalidDataViewAccessorOffset); } - let littleEndian: bool = ToBoolean(requestedLittleEndian); - let buffer: JSArrayBuffer = dataView.buffer; + const littleEndian: bool = ToBoolean(requestedLittleEndian); + const buffer: JSArrayBuffer = dataView.buffer; if (IsDetachedBuffer(buffer)) { ThrowTypeError(kDetachedOperation, MakeDataViewGetterNameString(kind)); } - let getIndexFloat: float64 = Convert<float64>(getIndex); - let getIndexWord: uintptr = Convert<uintptr>(getIndexFloat); + const getIndexFloat: float64 = Convert<float64>(getIndex); + const getIndexWord: uintptr = Convert<uintptr>(getIndexFloat); - let viewOffsetWord: uintptr = dataView.byte_offset; - let viewSizeFloat: float64 = Convert<float64>(dataView.byte_length); - let elementSizeFloat: float64 = DataViewElementSize(kind); + const viewOffsetWord: uintptr = dataView.byte_offset; + const viewSizeFloat: float64 = Convert<float64>(dataView.byte_length); + const elementSizeFloat: float64 = DataViewElementSize(kind); if (getIndexFloat + elementSizeFloat > viewSizeFloat) { ThrowRangeError(kInvalidDataViewAccessorOffset); } - let bufferIndex: uintptr = getIndexWord + viewOffsetWord; + const bufferIndex: uintptr = getIndexWord + viewOffsetWord; if constexpr (kind == UINT8_ELEMENTS) { return LoadDataView8(buffer, bufferIndex, false); @@ -442,84 +416,84 @@ namespace data_view { } transitioning javascript builtin DataViewPrototypeGetUint8( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; return DataViewGet(context, receiver, offset, Undefined, UINT8_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetInt8( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; return DataViewGet(context, receiver, offset, Undefined, INT8_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetUint16( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, UINT16_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetInt16( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, INT16_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetUint32( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, UINT32_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetInt32( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, INT32_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetFloat32( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, FLOAT32_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetFloat64( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, FLOAT64_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetBigUint64( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, BIGUINT64_ELEMENTS); } transitioning javascript builtin DataViewPrototypeGetBigInt64( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const isLittleEndian: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewGet( context, receiver, offset, isLittleEndian, BIGINT64_ELEMENTS); @@ -539,10 +513,10 @@ namespace data_view { macro StoreDataView16( buffer: JSArrayBuffer, offset: uintptr, value: uint32, requestedLittleEndian: bool) { - let dataPointer: RawPtr = buffer.backing_store; + const dataPointer: RawPtr = buffer.backing_store; - let b0: uint32 = value & 0xFF; - let b1: uint32 = (value >>> 8) & 0xFF; + const b0: uint32 = value & 0xFF; + const b1: uint32 = (value >>> 8) & 0xFF; if (requestedLittleEndian) { StoreWord8(dataPointer, offset, b0); @@ -556,12 +530,12 @@ namespace data_view { macro StoreDataView32( buffer: JSArrayBuffer, offset: uintptr, value: uint32, requestedLittleEndian: bool) { - let dataPointer: RawPtr = buffer.backing_store; + const dataPointer: RawPtr = buffer.backing_store; - let b0: uint32 = value & 0xFF; - let b1: uint32 = (value >>> 8) & 0xFF; - let b2: uint32 = (value >>> 16) & 0xFF; - let b3: uint32 = value >>> 24; // We don't need to mask here. + const b0: uint32 = value & 0xFF; + const b1: uint32 = (value >>> 8) & 0xFF; + const b2: uint32 = (value >>> 16) & 0xFF; + const b3: uint32 = value >>> 24; // We don't need to mask here. if (requestedLittleEndian) { StoreWord8(dataPointer, offset, b0); @@ -579,17 +553,17 @@ namespace data_view { macro StoreDataView64( buffer: JSArrayBuffer, offset: uintptr, lowWord: uint32, highWord: uint32, requestedLittleEndian: bool) { - let dataPointer: RawPtr = buffer.backing_store; + const dataPointer: RawPtr = buffer.backing_store; - let b0: uint32 = lowWord & 0xFF; - let b1: uint32 = (lowWord >>> 8) & 0xFF; - let b2: uint32 = (lowWord >>> 16) & 0xFF; - let b3: uint32 = lowWord >>> 24; + const b0: uint32 = lowWord & 0xFF; + const b1: uint32 = (lowWord >>> 8) & 0xFF; + const b2: uint32 = (lowWord >>> 16) & 0xFF; + const b3: uint32 = lowWord >>> 24; - let b4: uint32 = highWord & 0xFF; - let b5: uint32 = (highWord >>> 8) & 0xFF; - let b6: uint32 = (highWord >>> 16) & 0xFF; - let b7: uint32 = highWord >>> 24; + const b4: uint32 = highWord & 0xFF; + const b5: uint32 = (highWord >>> 8) & 0xFF; + const b6: uint32 = (highWord >>> 16) & 0xFF; + const b7: uint32 = highWord >>> 24; if (requestedLittleEndian) { StoreWord8(dataPointer, offset, b0); @@ -612,11 +586,10 @@ namespace data_view { } } - extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntLength(BigInt): - uint32; - extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntSign(BigInt): + extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntLength( + BigIntBase): uint32; + extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntSign(BigIntBase): uint32; - extern macro LoadBigIntDigit(BigInt, constexpr int31): uintptr; // We might get here a BigInt that is bigger than 64 bits, but we're only // interested in the 64 lowest ones. This means the lowest BigInt digit @@ -624,8 +597,8 @@ namespace data_view { macro StoreDataViewBigInt( buffer: JSArrayBuffer, offset: uintptr, bigIntValue: BigInt, requestedLittleEndian: bool) { - let length: uint32 = DataViewDecodeBigIntLength(bigIntValue); - let sign: uint32 = DataViewDecodeBigIntSign(bigIntValue); + const length: uint32 = DataViewDecodeBigIntLength(bigIntValue); + const sign: uint32 = DataViewDecodeBigIntSign(bigIntValue); // The 32-bit words that will hold the BigInt's value in // two's complement representation. @@ -636,13 +609,13 @@ namespace data_view { if (length != 0) { if constexpr (Is64()) { // There is always exactly 1 BigInt digit to load in this case. - let value: uintptr = LoadBigIntDigit(bigIntValue, 0); + const value: uintptr = bigint::LoadBigIntDigit(bigIntValue, 0); lowWord = Convert<uint32>(value); // Truncates value to 32 bits. highWord = Convert<uint32>(value >>> 32); } else { // There might be either 1 or 2 BigInt digits we need to load. - lowWord = Convert<uint32>(LoadBigIntDigit(bigIntValue, 0)); + lowWord = Convert<uint32>(bigint::LoadBigIntDigit(bigIntValue, 0)); if (length >= 2) { // Only load the second digit if there is one. - highWord = Convert<uint32>(LoadBigIntDigit(bigIntValue, 1)); + highWord = Convert<uint32>(bigint::LoadBigIntDigit(bigIntValue, 1)); } } } @@ -661,7 +634,7 @@ namespace data_view { transitioning macro DataViewSet( context: Context, receiver: Object, offset: Object, value: Object, requestedLittleEndian: Object, kind: constexpr ElementsKind): Object { - let dataView: JSDataView = + const dataView: JSDataView = ValidateDataView(context, receiver, MakeDataViewSetterNameString(kind)); let getIndex: Number; @@ -672,52 +645,52 @@ namespace data_view { ThrowRangeError(kInvalidDataViewAccessorOffset); } - let littleEndian: bool = ToBoolean(requestedLittleEndian); - let buffer: JSArrayBuffer = dataView.buffer; + const littleEndian: bool = ToBoolean(requestedLittleEndian); + const buffer: JSArrayBuffer = dataView.buffer; // According to ES6 section 24.2.1.2 SetViewValue, we must perform // the conversion before doing the bounds check. if constexpr (kind == BIGUINT64_ELEMENTS || kind == BIGINT64_ELEMENTS) { - let bigIntValue: BigInt = ToBigInt(context, value); + const bigIntValue: BigInt = ToBigInt(context, value); if (IsDetachedBuffer(buffer)) { ThrowTypeError(kDetachedOperation, MakeDataViewSetterNameString(kind)); } - let getIndexFloat: float64 = Convert<float64>(getIndex); - let getIndexWord: uintptr = Convert<uintptr>(getIndexFloat); + const getIndexFloat: float64 = Convert<float64>(getIndex); + const getIndexWord: uintptr = Convert<uintptr>(getIndexFloat); - let viewOffsetWord: uintptr = dataView.byte_offset; - let viewSizeFloat: float64 = Convert<float64>(dataView.byte_length); - let elementSizeFloat: float64 = DataViewElementSize(kind); + const viewOffsetWord: uintptr = dataView.byte_offset; + const viewSizeFloat: float64 = Convert<float64>(dataView.byte_length); + const elementSizeFloat: float64 = DataViewElementSize(kind); if (getIndexFloat + elementSizeFloat > viewSizeFloat) { ThrowRangeError(kInvalidDataViewAccessorOffset); } - let bufferIndex: uintptr = getIndexWord + viewOffsetWord; + const bufferIndex: uintptr = getIndexWord + viewOffsetWord; StoreDataViewBigInt(buffer, bufferIndex, bigIntValue, littleEndian); } else { - let numValue: Number = ToNumber(context, value); + const numValue: Number = ToNumber(context, value); if (IsDetachedBuffer(buffer)) { ThrowTypeError(kDetachedOperation, MakeDataViewSetterNameString(kind)); } - let getIndexFloat: float64 = Convert<float64>(getIndex); - let getIndexWord: uintptr = Convert<uintptr>(getIndexFloat); + const getIndexFloat: float64 = Convert<float64>(getIndex); + const getIndexWord: uintptr = Convert<uintptr>(getIndexFloat); - let viewOffsetWord: uintptr = dataView.byte_offset; - let viewSizeFloat: float64 = Convert<float64>(dataView.byte_length); - let elementSizeFloat: float64 = DataViewElementSize(kind); + const viewOffsetWord: uintptr = dataView.byte_offset; + const viewSizeFloat: float64 = Convert<float64>(dataView.byte_length); + const elementSizeFloat: float64 = DataViewElementSize(kind); if (getIndexFloat + elementSizeFloat > viewSizeFloat) { ThrowRangeError(kInvalidDataViewAccessorOffset); } - let bufferIndex: uintptr = getIndexWord + viewOffsetWord; + const bufferIndex: uintptr = getIndexWord + viewOffsetWord; - let doubleValue: float64 = ChangeNumberToFloat64(numValue); + const doubleValue: float64 = ChangeNumberToFloat64(numValue); if constexpr (kind == UINT8_ELEMENTS || kind == INT8_ELEMENTS) { StoreDataView8( @@ -731,13 +704,13 @@ namespace data_view { buffer, bufferIndex, TruncateFloat64ToWord32(doubleValue), littleEndian); } else if constexpr (kind == FLOAT32_ELEMENTS) { - let floatValue: float32 = TruncateFloat64ToFloat32(doubleValue); + const floatValue: float32 = TruncateFloat64ToFloat32(doubleValue); StoreDataView32( buffer, bufferIndex, BitcastFloat32ToInt32(floatValue), littleEndian); } else if constexpr (kind == FLOAT64_ELEMENTS) { - let lowWord: uint32 = Float64ExtractLowWord32(doubleValue); - let highWord: uint32 = Float64ExtractHighWord32(doubleValue); + const lowWord: uint32 = Float64ExtractLowWord32(doubleValue); + const highWord: uint32 = Float64ExtractHighWord32(doubleValue); StoreDataView64(buffer, bufferIndex, lowWord, highWord, littleEndian); } } @@ -745,96 +718,96 @@ namespace data_view { } transitioning javascript builtin DataViewPrototypeSetUint8( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewSet( context, receiver, offset, value, Undefined, UINT8_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetInt8( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; return DataViewSet( context, receiver, offset, value, Undefined, INT8_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetUint16( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, UINT16_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetInt16( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, INT16_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetUint32( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, UINT32_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetInt32( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, INT32_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetFloat32( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, FLOAT32_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetFloat64( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, FLOAT64_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetBigUint64( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, BIGUINT64_ELEMENTS); } transitioning javascript builtin DataViewPrototypeSetBigInt64( - context: Context, receiver: Object, ...arguments): Object { - let offset: Object = arguments.length > 0 ? arguments[0] : Undefined; - let value: Object = arguments.length > 1 ? arguments[1] : Undefined; - let isLittleEndian: Object = + js-implicit context: Context, receiver: Object)(...arguments): Object { + const offset: Object = arguments.length > 0 ? arguments[0] : Undefined; + const value: Object = arguments.length > 1 ? arguments[1] : Undefined; + const isLittleEndian: Object = arguments.length > 2 ? arguments[2] : Undefined; return DataViewSet( context, receiver, offset, value, isLittleEndian, BIGINT64_ELEMENTS); diff --git a/deps/v8/src/builtins/extras-utils.tq b/deps/v8/src/builtins/extras-utils.tq index 2b9b79739e..3675fda191 100644 --- a/deps/v8/src/builtins/extras-utils.tq +++ b/deps/v8/src/builtins/extras-utils.tq @@ -8,17 +8,18 @@ namespace extras_utils { extern runtime PromiseStatus(Context, Object): Smi; javascript builtin ExtrasUtilsCreatePrivateSymbol( - context: Context, receiver: Object, ...arguments): HeapObject { + js-implicit context: Context, + receiver: Object)(...arguments): HeapObject { return CreatePrivateSymbol(context, arguments[0]); } javascript builtin ExtrasUtilsMarkPromiseAsHandled( - context: Context, receiver: Object, ...arguments): Undefined { + js-implicit context: Context, receiver: Object)(...arguments): Undefined { return PromiseMarkAsHandled(context, arguments[0]); } javascript builtin ExtrasUtilsPromiseState( - context: Context, receiver: Object, ...arguments): Smi { + js-implicit context: Context, receiver: Object)(...arguments): Smi { return PromiseStatus(context, arguments[0]); } } diff --git a/deps/v8/src/builtins/ia32/builtins-ia32.cc b/deps/v8/src/builtins/ia32/builtins-ia32.cc index 0d80c681fb..995be77f75 100644 --- a/deps/v8/src/builtins/ia32/builtins-ia32.cc +++ b/deps/v8/src/builtins/ia32/builtins-ia32.cc @@ -1023,10 +1023,10 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // 8-bit fields next to each other, so we could just optimize by writing a // 16-bit. These static asserts guard our assumption is valid. STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == - BytecodeArray::kOSRNestingLevelOffset + kCharSize); + BytecodeArray::kOsrNestingLevelOffset + kCharSize); STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); __ mov_w(FieldOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kOSRNestingLevelOffset), + BytecodeArray::kOsrNestingLevelOffset), Immediate(0)); // Push bytecode array. @@ -1534,6 +1534,15 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, BuiltinContinuationFrameConstants::kFixedFrameSize), eax); } + + // Replace the builtin index Smi on the stack with the start address of the + // builtin loaded from the builtins table. The ret below will return to this + // address. + int offset_to_builtin_index = allocatable_register_count * kSystemPointerSize; + __ mov(eax, Operand(esp, offset_to_builtin_index)); + __ LoadEntryFromBuiltinIndex(eax); + __ mov(Operand(esp, offset_to_builtin_index), eax); + for (int i = allocatable_register_count - 1; i >= 0; --i) { int code = config->GetAllocatableGeneralCode(i); __ pop(Register::from_code(code)); @@ -1549,7 +1558,6 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, kSystemPointerSize; __ pop(Operand(esp, offsetToPC)); __ Drop(offsetToPC / kSystemPointerSize); - __ add(Operand(esp, 0), Immediate(Code::kHeaderSize - kHeapObjectTag)); __ ret(0); } } // namespace @@ -3012,23 +3020,28 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, __ mov(esi, __ ExternalReferenceAsOperand(next_address, esi)); __ mov(edi, __ ExternalReferenceAsOperand(limit_address, edi)); - Label profiler_disabled; - Label end_profiler_check; + Label profiler_enabled, end_profiler_check; __ Move(eax, Immediate(ExternalReference::is_profiling_address(isolate))); __ cmpb(Operand(eax, 0), Immediate(0)); - __ j(zero, &profiler_disabled); + __ j(not_zero, &profiler_enabled); + __ Move(eax, Immediate(ExternalReference::address_of_runtime_stats_flag())); + __ cmp(Operand(eax, 0), Immediate(0)); + __ j(not_zero, &profiler_enabled); + { + // Call the api function directly. + __ mov(eax, function_address); + __ jmp(&end_profiler_check); + } + __ bind(&profiler_enabled); + { + // Additional parameter is the address of the actual getter function. + __ mov(thunk_last_arg, function_address); + __ Move(eax, Immediate(thunk_ref)); + } + __ bind(&end_profiler_check); - // Additional parameter is the address of the actual getter function. - __ mov(thunk_last_arg, function_address); // Call the api function. - __ Move(eax, Immediate(thunk_ref)); __ call(eax); - __ jmp(&end_profiler_check); - - __ bind(&profiler_disabled); - // Call the api function. - __ call(function_address); - __ bind(&end_profiler_check); Label prologue; // Load the value from ReturnValue @@ -3080,6 +3093,9 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, __ CompareRoot(map, RootIndex::kHeapNumberMap); __ j(equal, &ok, Label::kNear); + __ CompareRoot(map, RootIndex::kBigIntMap); + __ j(equal, &ok, Label::kNear); + __ CompareRoot(return_value, RootIndex::kUndefinedValue); __ j(equal, &ok, Label::kNear); diff --git a/deps/v8/src/builtins/internal-coverage.tq b/deps/v8/src/builtins/internal-coverage.tq index 4e75c6d837..d96fa924ab 100644 --- a/deps/v8/src/builtins/internal-coverage.tq +++ b/deps/v8/src/builtins/internal-coverage.tq @@ -28,6 +28,8 @@ namespace internal_coverage { return UnsafeCast<CoverageInfo>(debugInfo.coverage_info); } + @export // Silence unused warning on release builds. SlotCount is only used + // in an assert. TODO(szuend): Remove once macros and asserts work. macro SlotCount(coverageInfo: CoverageInfo): Smi { assert(kFirstSlotIndex == 0); // Otherwise we'd have to consider it below. assert(kFirstSlotIndex == (coverageInfo.length & kSlotIndexCountMask)); diff --git a/deps/v8/src/builtins/iterator.tq b/deps/v8/src/builtins/iterator.tq index 5c9439dfc7..b770f1b652 100644 --- a/deps/v8/src/builtins/iterator.tq +++ b/deps/v8/src/builtins/iterator.tq @@ -20,16 +20,16 @@ namespace iterator { implicit context: Context)(Object): IteratorRecord; extern macro IteratorBuiltinsAssembler::IteratorStep( - implicit context: Context)(IteratorRecord): Object + implicit context: Context)(IteratorRecord): JSReceiver labels Done; extern macro IteratorBuiltinsAssembler::IteratorStep( - implicit context: Context)(IteratorRecord, Map): Object + implicit context: Context)(IteratorRecord, Map): JSReceiver labels Done; extern macro IteratorBuiltinsAssembler::IteratorValue( - implicit context: Context)(Object): Object; + implicit context: Context)(JSReceiver): Object; extern macro IteratorBuiltinsAssembler::IteratorValue( - implicit context: Context)(Object, Map): Object; + implicit context: Context)(JSReceiver, Map): Object; extern macro IteratorBuiltinsAssembler::IteratorCloseOnException( implicit context: Context)(IteratorRecord, Object): never; diff --git a/deps/v8/src/builtins/math.tq b/deps/v8/src/builtins/math.tq index 84dd1261fa..df43b30efc 100644 --- a/deps/v8/src/builtins/math.tq +++ b/deps/v8/src/builtins/math.tq @@ -7,7 +7,7 @@ namespace math { extern macro Float64Acos(float64): float64; transitioning javascript builtin - MathAcos(context: Context, receiver: Object, x: Object): Number { + MathAcos(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Acos(value)); } @@ -16,7 +16,7 @@ namespace math { extern macro Float64Acosh(float64): float64; transitioning javascript builtin - MathAcosh(context: Context, receiver: Object, x: Object): Number { + MathAcosh(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Acosh(value)); } @@ -25,7 +25,7 @@ namespace math { extern macro Float64Asin(float64): float64; transitioning javascript builtin - MathAsin(context: Context, receiver: Object, x: Object): Number { + MathAsin(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Asin(value)); } @@ -34,7 +34,7 @@ namespace math { extern macro Float64Asinh(float64): float64; transitioning javascript builtin - MathAsinh(context: Context, receiver: Object, x: Object): Number { + MathAsinh(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Asinh(value)); } @@ -43,7 +43,7 @@ namespace math { extern macro Float64Atan(float64): float64; transitioning javascript builtin - MathAtan(context: Context, receiver: Object, x: Object): Number { + MathAtan(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Atan(value)); } @@ -52,7 +52,7 @@ namespace math { extern macro Float64Atan2(float64, float64): float64; transitioning javascript builtin - MathAtan2(context: Context, receiver: Object, y: Object, x: Object): Number { + MathAtan2(context: Context, _receiver: Object, y: Object, x: Object): Number { const yValue = Convert<float64>(ToNumber_Inline(context, y)); const xValue = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Atan2(yValue, xValue)); @@ -62,7 +62,7 @@ namespace math { extern macro Float64Atanh(float64): float64; transitioning javascript builtin - MathAtanh(context: Context, receiver: Object, x: Object): Number { + MathAtanh(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Atanh(value)); } @@ -71,7 +71,7 @@ namespace math { extern macro Float64Cbrt(float64): float64; transitioning javascript builtin - MathCbrt(context: Context, receiver: Object, x: Object): Number { + MathCbrt(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Cbrt(value)); } @@ -80,7 +80,7 @@ namespace math { extern macro Word32Clz(int32): int32; transitioning javascript builtin - MathClz32(context: Context, receiver: Object, x: Object): Number { + MathClz32(context: Context, _receiver: Object, x: Object): Number { const num = ToNumber_Inline(context, x); let value: int32; @@ -100,7 +100,7 @@ namespace math { extern macro Float64Cos(float64): float64; transitioning javascript builtin - MathCos(context: Context, receiver: Object, x: Object): Number { + MathCos(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Cos(value)); } @@ -109,7 +109,7 @@ namespace math { extern macro Float64Cosh(float64): float64; transitioning javascript builtin - MathCosh(context: Context, receiver: Object, x: Object): Number { + MathCosh(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Cosh(value)); } @@ -118,7 +118,7 @@ namespace math { extern macro Float64Exp(float64): float64; transitioning javascript builtin - MathExp(context: Context, receiver: Object, x: Object): Number { + MathExp(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Exp(value)); } @@ -127,14 +127,14 @@ namespace math { extern macro Float64Expm1(float64): float64; transitioning javascript builtin - MathExpm1(context: Context, receiver: Object, x: Object): Number { + MathExpm1(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Expm1(value)); } // ES6 #sec-math.fround transitioning javascript builtin - MathFround(context: Context, receiver: Object, x: Object): Number { + MathFround(context: Context, _receiver: Object, x: Object): Number { const x32 = Convert<float32>(ToNumber_Inline(context, x)); const x64 = Convert<float64>(x32); return Convert<Number>(x64); @@ -144,7 +144,7 @@ namespace math { extern macro Float64Log(float64): float64; transitioning javascript builtin - MathLog(context: Context, receiver: Object, x: Object): Number { + MathLog(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Log(value)); } @@ -153,7 +153,7 @@ namespace math { extern macro Float64Log1p(float64): float64; transitioning javascript builtin - MathLog1p(context: Context, receiver: Object, x: Object): Number { + MathLog1p(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Log1p(value)); } @@ -162,7 +162,7 @@ namespace math { extern macro Float64Log10(float64): float64; transitioning javascript builtin - MathLog10(context: Context, receiver: Object, x: Object): Number { + MathLog10(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Log10(value)); } @@ -171,7 +171,7 @@ namespace math { extern macro Float64Log2(float64): float64; transitioning javascript builtin - MathLog2(context: Context, receiver: Object, x: Object): Number { + MathLog2(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Log2(value)); } @@ -180,14 +180,14 @@ namespace math { extern macro Float64Sin(float64): float64; transitioning javascript builtin - MathSin(context: Context, receiver: Object, x: Object): Number { + MathSin(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Sin(value)); } // ES6 #sec-math.sign transitioning javascript builtin - MathSign(context: Context, receiver: Object, x: Object): Number { + MathSign(context: Context, _receiver: Object, x: Object): Number { const num = ToNumber_Inline(context, x); const value = Convert<float64>(num); @@ -204,7 +204,7 @@ namespace math { extern macro Float64Sinh(float64): float64; transitioning javascript builtin - MathSinh(context: Context, receiver: Object, x: Object): Number { + MathSinh(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Sinh(value)); } @@ -213,7 +213,7 @@ namespace math { extern macro Float64Sqrt(float64): float64; transitioning javascript builtin - MathSqrt(context: Context, receiver: Object, x: Object): Number { + MathSqrt(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Sqrt(value)); } @@ -222,7 +222,7 @@ namespace math { extern macro Float64Tan(float64): float64; transitioning javascript builtin - MathTan(context: Context, receiver: Object, x: Object): Number { + MathTan(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Tan(value)); } @@ -231,7 +231,7 @@ namespace math { extern macro Float64Tanh(float64): float64; transitioning javascript builtin - MathTanh(context: Context, receiver: Object, x: Object): Number { + MathTanh(context: Context, _receiver: Object, x: Object): Number { const value = Convert<float64>(ToNumber_Inline(context, x)); return Convert<Number>(Float64Tanh(value)); } diff --git a/deps/v8/src/builtins/mips/builtins-mips.cc b/deps/v8/src/builtins/mips/builtins-mips.cc index ec65c78ee9..a359b2436f 100644 --- a/deps/v8/src/builtins/mips/builtins-mips.cc +++ b/deps/v8/src/builtins/mips/builtins-mips.cc @@ -62,7 +62,6 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) { static void GenerateTailCallToReturnedCode(MacroAssembler* masm, Runtime::FunctionId function_id) { // ----------- S t a t e ------------- - // -- a0 : argument count (preserved for callee) // -- a1 : target function (preserved for callee) // -- a3 : new target (preserved for callee) // ----------------------------------- @@ -70,14 +69,12 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm, FrameScope scope(masm, StackFrame::INTERNAL); // Push a copy of the target function and the new target. // Push function as parameter to the runtime call. - __ SmiTag(a0); - __ Push(a0, a1, a3, a1); + __ Push(a1, a3, a1); __ CallRuntime(function_id, 1); // Restore target function and new target. - __ Pop(a0, a1, a3); - __ SmiUntag(a0); + __ Pop(a1, a3); } static_assert(kJavaScriptCallCodeStartRegister == a2, "ABI mismatch"); @@ -853,13 +850,11 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, Register scratch1, Register scratch2, Register scratch3) { // ----------- S t a t e ------------- - // -- a0 : argument count (preserved for callee if needed, and caller) // -- a3 : new target (preserved for callee if needed, and caller) // -- a1 : target function (preserved for callee if needed, and caller) // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK( - !AreAliased(feedback_vector, a0, a1, a3, scratch1, scratch2, scratch3)); + DCHECK(!AreAliased(feedback_vector, a1, a3, scratch1, scratch2, scratch3)); Label optimized_code_slot_is_weak_ref, fallthrough; @@ -1035,17 +1030,18 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ lw(feedback_vector, FieldMemOperand(closure, JSFunction::kFeedbackCellOffset)); __ lw(feedback_vector, FieldMemOperand(feedback_vector, Cell::kValueOffset)); + + Label push_stack_frame; + // Check if feedback vector is valid. If valid, check for optimized code + // and update invocation count. Otherwise, setup the stack frame. + __ lw(t0, FieldMemOperand(feedback_vector, HeapObject::kMapOffset)); + __ lhu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); + __ Branch(&push_stack_frame, ne, t0, Operand(FEEDBACK_VECTOR_TYPE)); + // Read off the optimized code slot in the feedback vector, and if there // is optimized code or an optimization marker, call that instead. MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, t0, t3, t1); - // Open a frame scope to indicate that there is a frame on the stack. The - // MANUAL indicates that the scope shouldn't actually generate code to set up - // the frame (that is done below). - FrameScope frame_scope(masm, StackFrame::MANUAL); - __ PushStandardFrame(closure); - - // Increment invocation count for the function. __ lw(t0, FieldMemOperand(feedback_vector, FeedbackVector::kInvocationCountOffset)); @@ -1053,10 +1049,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ sw(t0, FieldMemOperand(feedback_vector, FeedbackVector::kInvocationCountOffset)); - // Reset code age. - DCHECK_EQ(0, BytecodeArray::kNoAgeBytecodeAge); - __ sb(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kBytecodeAgeOffset)); + // Open a frame scope to indicate that there is a frame on the stack. The + // MANUAL indicates that the scope shouldn't actually generate code to set up + // the frame (that is done below). + __ bind(&push_stack_frame); + FrameScope frame_scope(masm, StackFrame::MANUAL); + __ PushStandardFrame(closure); + + // Reset code age and the OSR arming. The OSR field and BytecodeAgeOffset are + // 8-bit fields next to each other, so we could just optimize by writing a + // 16-bit. These static asserts guard our assumption is valid. + STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == + BytecodeArray::kOsrNestingLevelOffset + kCharSize); + STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); + __ sh(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kOsrNestingLevelOffset)); // Load initial bytecode offset. __ li(kInterpreterBytecodeOffsetRegister, @@ -1464,11 +1471,13 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, } __ lw(fp, MemOperand( sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); + // Load builtin index (stored as a Smi) and use it to get the builtin start + // address from the builtins table. __ Pop(t0); __ Addu(sp, sp, Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); __ Pop(ra); - __ Addu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); + __ LoadEntryFromBuiltinIndex(t0); __ Jump(t0); } } // namespace @@ -2559,7 +2568,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, __ LoadRoot(t0, RootIndex::kTheHoleValue); // Cannot use check here as it attempts to generate call into runtime. __ Branch(&okay, eq, t0, Operand(a2)); - __ stop("Unexpected pending exception"); + __ stop(); __ bind(&okay); } @@ -2825,18 +2834,23 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, DCHECK(function_address == a1 || function_address == a2); - Label profiler_disabled; - Label end_profiler_check; + Label profiler_enabled, end_profiler_check; __ li(t9, ExternalReference::is_profiling_address(isolate)); __ lb(t9, MemOperand(t9, 0)); - __ Branch(&profiler_disabled, eq, t9, Operand(zero_reg)); - - // Additional parameter is the address of the actual callback. - __ li(t9, thunk_ref); - __ jmp(&end_profiler_check); - - __ bind(&profiler_disabled); - __ mov(t9, function_address); + __ Branch(&profiler_enabled, ne, t9, Operand(zero_reg)); + __ li(t9, ExternalReference::address_of_runtime_stats_flag()); + __ lw(t9, MemOperand(t9, 0)); + __ Branch(&profiler_enabled, ne, t9, Operand(zero_reg)); + { + // Call the api function directly. + __ mov(t9, function_address); + __ Branch(&end_profiler_check); + } + __ bind(&profiler_enabled); + { + // Additional parameter is the address of the actual callback. + __ li(t9, thunk_ref); + } __ bind(&end_profiler_check); // Allocate HandleScope in callee-save registers. diff --git a/deps/v8/src/builtins/mips64/builtins-mips64.cc b/deps/v8/src/builtins/mips64/builtins-mips64.cc index 34a5774d65..c5565b90de 100644 --- a/deps/v8/src/builtins/mips64/builtins-mips64.cc +++ b/deps/v8/src/builtins/mips64/builtins-mips64.cc @@ -62,7 +62,6 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) { static void GenerateTailCallToReturnedCode(MacroAssembler* masm, Runtime::FunctionId function_id) { // ----------- S t a t e ------------- - // -- a0 : argument count (preserved for callee) // -- a1 : target function (preserved for callee) // -- a3 : new target (preserved for callee) // ----------------------------------- @@ -70,13 +69,11 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm, FrameScope scope(masm, StackFrame::INTERNAL); // Push a copy of the function onto the stack. // Push a copy of the target function and the new target. - __ SmiTag(a0); - __ Push(a0, a1, a3, a1); + __ Push(a1, a3, a1); __ CallRuntime(function_id, 1); // Restore target function and new target. - __ Pop(a0, a1, a3); - __ SmiUntag(a0); + __ Pop(a1, a3); } static_assert(kJavaScriptCallCodeStartRegister == a2, "ABI mismatch"); @@ -870,13 +867,11 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, Register scratch1, Register scratch2, Register scratch3) { // ----------- S t a t e ------------- - // -- a0 : argument count (preserved for callee if needed, and caller) // -- a3 : new target (preserved for callee if needed, and caller) // -- a1 : target function (preserved for callee if needed, and caller) // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK( - !AreAliased(feedback_vector, a0, a1, a3, scratch1, scratch2, scratch3)); + DCHECK(!AreAliased(feedback_vector, a1, a3, scratch1, scratch2, scratch3)); Label optimized_code_slot_is_weak_ref, fallthrough; @@ -1052,16 +1047,18 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Ld(feedback_vector, FieldMemOperand(closure, JSFunction::kFeedbackCellOffset)); __ Ld(feedback_vector, FieldMemOperand(feedback_vector, Cell::kValueOffset)); + + Label push_stack_frame; + // Check if feedback vector is valid. If valid, check for optimized code + // and update invocation count. Otherwise, setup the stack frame. + __ Ld(a4, FieldMemOperand(feedback_vector, HeapObject::kMapOffset)); + __ Lhu(a4, FieldMemOperand(a4, Map::kInstanceTypeOffset)); + __ Branch(&push_stack_frame, ne, a4, Operand(FEEDBACK_VECTOR_TYPE)); + // Read off the optimized code slot in the feedback vector, and if there // is optimized code or an optimization marker, call that instead. MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, a4, t3, a5); - // Open a frame scope to indicate that there is a frame on the stack. The - // MANUAL indicates that the scope shouldn't actually generate code to set up - // the frame (that is done below). - FrameScope frame_scope(masm, StackFrame::MANUAL); - __ PushStandardFrame(closure); - // Increment invocation count for the function. __ Lw(a4, FieldMemOperand(feedback_vector, FeedbackVector::kInvocationCountOffset)); @@ -1069,10 +1066,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Sw(a4, FieldMemOperand(feedback_vector, FeedbackVector::kInvocationCountOffset)); - // Reset code age. - DCHECK_EQ(0, BytecodeArray::kNoAgeBytecodeAge); - __ sb(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kBytecodeAgeOffset)); + // Open a frame scope to indicate that there is a frame on the stack. The + // MANUAL indicates that the scope shouldn't actually generate code to set up + // the frame (that is done below). + __ bind(&push_stack_frame); + FrameScope frame_scope(masm, StackFrame::MANUAL); + __ PushStandardFrame(closure); + + // Reset code age and the OSR arming. The OSR field and BytecodeAgeOffset are + // 8-bit fields next to each other, so we could just optimize by writing a + // 16-bit. These static asserts guard our assumption is valid. + STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == + BytecodeArray::kOsrNestingLevelOffset + kCharSize); + STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); + __ sh(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kOsrNestingLevelOffset)); // Load initial bytecode offset. __ li(kInterpreterBytecodeOffsetRegister, @@ -1479,11 +1487,13 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, } __ Ld(fp, MemOperand( sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); + // Load builtin index (stored as a Smi) and use it to get the builtin start + // address from the builtins table. __ Pop(t0); __ Daddu(sp, sp, Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); __ Pop(ra); - __ Daddu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); + __ LoadEntryFromBuiltinIndex(t0); __ Jump(t0); } } // namespace @@ -2595,7 +2605,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, __ LoadRoot(a4, RootIndex::kTheHoleValue); // Cannot use check here as it attempts to generate call into runtime. __ Branch(&okay, eq, a4, Operand(a2)); - __ stop("Unexpected pending exception"); + __ stop(); __ bind(&okay); } @@ -2864,18 +2874,24 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, DCHECK(function_address == a1 || function_address == a2); - Label profiler_disabled; - Label end_profiler_check; + Label profiler_enabled, end_profiler_check; __ li(t9, ExternalReference::is_profiling_address(isolate)); __ Lb(t9, MemOperand(t9, 0)); - __ Branch(&profiler_disabled, eq, t9, Operand(zero_reg)); - - // Additional parameter is the address of the actual callback. - __ li(t9, thunk_ref); - __ jmp(&end_profiler_check); + __ Branch(&profiler_enabled, ne, t9, Operand(zero_reg)); + __ li(t9, ExternalReference::address_of_runtime_stats_flag()); + __ Lw(t9, MemOperand(t9, 0)); + __ Branch(&profiler_enabled, ne, t9, Operand(zero_reg)); + { + // Call the api function directly. + __ mov(t9, function_address); + __ Branch(&end_profiler_check); + } - __ bind(&profiler_disabled); - __ mov(t9, function_address); + __ bind(&profiler_enabled); + { + // Additional parameter is the address of the actual callback. + __ li(t9, thunk_ref); + } __ bind(&end_profiler_check); // Allocate HandleScope in callee-save registers. diff --git a/deps/v8/src/builtins/object-fromentries.tq b/deps/v8/src/builtins/object-fromentries.tq index 93851d4e11..32115e78ea 100644 --- a/deps/v8/src/builtins/object-fromentries.tq +++ b/deps/v8/src/builtins/object-fromentries.tq @@ -33,8 +33,8 @@ namespace object { } transitioning javascript builtin - ObjectFromEntries(implicit context: Context)(receiver: Object, ...arguments): - Object { + ObjectFromEntries(js-implicit context: Context, receiver: Object)( + ...arguments): Object { const iterable: Object = arguments[0]; try { if (IsNullOrUndefined(iterable)) goto Throw; @@ -47,7 +47,8 @@ namespace object { try { assert(!IsNullOrUndefined(i.object)); while (true) { - const step: Object = iterator::IteratorStep(i, fastIteratorResultMap) + const step: JSReceiver = + iterator::IteratorStep(i, fastIteratorResultMap) otherwise return result; const iteratorValue: Object = iterator::IteratorValue(step, fastIteratorResultMap); diff --git a/deps/v8/src/builtins/object.tq b/deps/v8/src/builtins/object.tq new file mode 100644 index 0000000000..6706a8f943 --- /dev/null +++ b/deps/v8/src/builtins/object.tq @@ -0,0 +1,138 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace runtime { + extern transitioning runtime + ObjectIsExtensible(implicit context: Context)(Object): Object; + + extern transitioning runtime + JSReceiverPreventExtensionsThrow(implicit context: Context)(JSReceiver): + Object; + + extern transitioning runtime + JSReceiverPreventExtensionsDontThrow(implicit context: Context)(JSReceiver): + Object; + + extern transitioning runtime + JSReceiverGetPrototypeOf(implicit context: Context)(JSReceiver): Object; + + extern transitioning runtime + JSReceiverSetPrototypeOfThrow(implicit context: Context)(JSReceiver, Object): + Object; + + extern transitioning runtime + JSReceiverSetPrototypeOfDontThrow(implicit context: + Context)(JSReceiver, Object): Object; +} // namespace runtime + +namespace object { + transitioning macro + ObjectIsExtensible(implicit context: Context)(object: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) otherwise return False; + const objectJSProxy = Cast<JSProxy>(objectJSReceiver) + otherwise return runtime::ObjectIsExtensible(objectJSReceiver); + return proxy::ProxyIsExtensible(objectJSProxy); + } + + transitioning macro + ObjectPreventExtensionsThrow(implicit context: Context)(object: Object): + Object { + const objectJSReceiver = Cast<JSReceiver>(object) otherwise return object; + const objectJSProxy = Cast<JSProxy>(objectJSReceiver) + otherwise return runtime::JSReceiverPreventExtensionsThrow( + objectJSReceiver); + proxy::ProxyPreventExtensions(objectJSProxy, True); + return objectJSReceiver; + } + + transitioning macro + ObjectPreventExtensionsDontThrow(implicit context: Context)(object: Object): + Object { + const objectJSReceiver = Cast<JSReceiver>(object) otherwise return False; + const objectJSProxy = Cast<JSProxy>(objectJSReceiver) + otherwise return runtime::JSReceiverPreventExtensionsDontThrow( + objectJSReceiver); + return proxy::ProxyPreventExtensions(objectJSProxy, False); + } + + transitioning macro + ObjectGetPrototypeOf(implicit context: Context)(object: Object): Object { + const objectJSReceiver: JSReceiver = ToObject_Inline(context, object); + return object::JSReceiverGetPrototypeOf(objectJSReceiver); + } + + transitioning macro + JSReceiverGetPrototypeOf(implicit context: Context)(object: JSReceiver): + Object { + const objectJSProxy = Cast<JSProxy>(object) + otherwise return runtime::JSReceiverGetPrototypeOf(object); + return proxy::ProxyGetPrototypeOf(objectJSProxy); + } + + transitioning macro + ObjectSetPrototypeOfThrow(implicit context: Context)( + object: Object, proto: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) otherwise return object; + const objectJSProxy = Cast<JSProxy>(objectJSReceiver) + otherwise return runtime::JSReceiverSetPrototypeOfThrow( + objectJSReceiver, proto); + proxy::ProxySetPrototypeOf(objectJSProxy, proto, True); + return objectJSReceiver; + } + + transitioning macro + ObjectSetPrototypeOfDontThrow(implicit context: Context)( + object: Object, proto: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) otherwise return False; + const objectJSProxy = Cast<JSProxy>(objectJSReceiver) + otherwise return runtime::JSReceiverSetPrototypeOfDontThrow( + objectJSReceiver, proto); + return proxy::ProxySetPrototypeOf(objectJSProxy, proto, False); + } +} // namespace object + +namespace object_isextensible { + // ES6 section 19.1.2.11 Object.isExtensible ( O ) + transitioning javascript builtin ObjectIsExtensible( + js-implicit context: Context)(_receiver: Object, object: Object): Object { + return object::ObjectIsExtensible(object); + } +} // namespace object_isextensible + +namespace object_preventextensions { + // ES6 section 19.1.2.11 Object.isExtensible ( O ) + transitioning javascript builtin ObjectPreventExtensions( + js-implicit context: Context)(_receiver: Object, object: Object): Object { + return object::ObjectPreventExtensionsThrow(object); + } +} // namespace object_preventextensions + +namespace object_getprototypeof { + // ES6 section 19.1.2.9 Object.getPrototypeOf ( O ) + transitioning javascript builtin ObjectGetPrototypeOf( + js-implicit context: Context)(_receiver: Object, object: Object): Object { + return object::ObjectGetPrototypeOf(object); + } +} // namespace object_getprototypeof + +namespace object_setprototypeof { + // ES6 section 19.1.2.21 Object.setPrototypeOf ( O, proto ) + transitioning javascript builtin ObjectSetPrototypeOf( + js-implicit context: + Context)(_receiver: Object, object: Object, proto: Object): Object { + // 1. Set O to ? RequireObjectCoercible(O). + RequireObjectCoercible(object, 'Object.setPrototypeOf'); + + // 2. If Type(proto) is neither Object nor Null, throw a TypeError + // exception. + // 3. If Type(O) is not Object, return O. + // 4. Let status be ? O.[[SetPrototypeOf]](proto). + // 5. If status is false, throw a TypeError exception. + // 6. Return O. + if (proto == Null || Is<JSReceiver>(proto)) { + return object::ObjectSetPrototypeOfThrow(object, proto); + } + ThrowTypeError(kProtoObjectOrNull, proto); + } +} // namespace object_setprototypeof diff --git a/deps/v8/src/builtins/ppc/builtins-ppc.cc b/deps/v8/src/builtins/ppc/builtins-ppc.cc index e3c6ce6407..a42cb9bebd 100644 --- a/deps/v8/src/builtins/ppc/builtins-ppc.cc +++ b/deps/v8/src/builtins/ppc/builtins-ppc.cc @@ -60,24 +60,20 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) { static void GenerateTailCallToReturnedCode(MacroAssembler* masm, Runtime::FunctionId function_id) { // ----------- S t a t e ------------- - // -- r3 : argument count (preserved for callee) // -- r4 : target function (preserved for callee) // -- r6 : new target (preserved for callee) // ----------------------------------- { FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - // Push the number of arguments to the callee. // Push a copy of the target function and the new target. // Push function as parameter to the runtime call. - __ SmiTag(r3); - __ Push(r3, r4, r6, r4); + __ Push(r4, r6, r4); __ CallRuntime(function_id, 1); __ mr(r5, r3); // Restore target function and new target. - __ Pop(r3, r4, r6); - __ SmiUntag(r3); + __ Pop(r4, r6); } static_assert(kJavaScriptCallCodeStartRegister == r5, "ABI mismatch"); __ JumpCodeObject(r5); @@ -110,6 +106,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { // -- sp[...]: constructor arguments // ----------------------------------- + Register scratch = r5; + Label stack_overflow; Generate_StackOverflowCheck(masm, r3, r8, &stack_overflow); @@ -141,13 +139,13 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { // -- sp[2*kPointerSize]: context // ----------------------------------- __ beq(&no_args, cr0); - __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2)); - __ sub(sp, sp, ip); + __ ShiftLeftImm(scratch, r3, Operand(kPointerSizeLog2)); + __ sub(sp, sp, scratch); __ mtctr(r3); __ bind(&loop); - __ subi(ip, ip, Operand(kPointerSize)); - __ LoadPX(r0, MemOperand(r7, ip)); - __ StorePX(r0, MemOperand(sp, ip)); + __ subi(scratch, scratch, Operand(kPointerSize)); + __ LoadPX(r0, MemOperand(r7, scratch)); + __ StorePX(r0, MemOperand(sp, scratch)); __ bdnz(&loop); __ bind(&no_args); @@ -300,13 +298,13 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { // ----------------------------------- __ cmpi(r3, Operand::Zero()); __ beq(&no_args); - __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2)); - __ sub(sp, sp, ip); + __ ShiftLeftImm(r9, r3, Operand(kPointerSizeLog2)); + __ sub(sp, sp, r9); __ mtctr(r3); __ bind(&loop); - __ subi(ip, ip, Operand(kPointerSize)); - __ LoadPX(r0, MemOperand(r7, ip)); - __ StorePX(r0, MemOperand(sp, ip)); + __ subi(r9, r9, Operand(kPointerSize)); + __ LoadPX(r0, MemOperand(r7, r9)); + __ StorePX(r0, MemOperand(sp, r9)); __ bdnz(&loop); __ bind(&no_args); @@ -416,12 +414,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { // Flood function if we are stepping. Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator; Label stepping_prepared; + Register scratch = r8; ExternalReference debug_hook = ExternalReference::debug_hook_on_function_call_address(masm->isolate()); - __ Move(ip, debug_hook); - __ LoadByte(ip, MemOperand(ip), r0); - __ extsb(ip, ip); - __ CmpSmiLiteral(ip, Smi::zero(), r0); + __ Move(scratch, debug_hook); + __ LoadByte(scratch, MemOperand(scratch), r0); + __ extsb(scratch, scratch); + __ CmpSmiLiteral(scratch, Smi::zero(), r0); __ bne(&prepare_step_in_if_stepping); // Flood function if we need to continue stepping in the suspended generator. @@ -429,9 +428,9 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { ExternalReference debug_suspended_generator = ExternalReference::debug_suspended_generator_address(masm->isolate()); - __ Move(ip, debug_suspended_generator); - __ LoadP(ip, MemOperand(ip)); - __ cmp(ip, r4); + __ Move(scratch, debug_suspended_generator); + __ LoadP(scratch, MemOperand(scratch)); + __ cmp(scratch, r4); __ beq(&prepare_step_in_suspended_generator); __ bind(&stepping_prepared); @@ -442,8 +441,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { __ blt(&stack_overflow); // Push receiver. - __ LoadP(ip, FieldMemOperand(r4, JSGeneratorObject::kReceiverOffset)); - __ Push(ip); + __ LoadP(scratch, FieldMemOperand(r4, JSGeneratorObject::kReceiverOffset)); + __ Push(scratch); // ----------- S t a t e ------------- // -- r4 : the JSGeneratorObject to resume @@ -470,8 +469,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { __ mtctr(r6); __ bind(&loop); - __ LoadPU(ip, MemOperand(r9, kPointerSize)); - __ push(ip); + __ LoadPU(scratch, MemOperand(r9, kPointerSize)); + __ push(scratch); __ bdnz(&loop); __ bind(&done_loop); @@ -602,6 +601,7 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, __ LoadP(r0, MemOperand(r3)); __ push(r0); + Register scratch = r9; // Set up frame pointer for the frame to be pushed. __ addi(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); @@ -611,17 +611,17 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, masm->isolate()); __ Move(r3, js_entry_sp); - __ LoadP(r9, MemOperand(r3)); - __ cmpi(r9, Operand::Zero()); + __ LoadP(scratch, MemOperand(r3)); + __ cmpi(scratch, Operand::Zero()); __ bne(&non_outermost_js); __ StoreP(fp, MemOperand(r3)); - __ mov(ip, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME)); + __ mov(scratch, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME)); Label cont; __ b(&cont); __ bind(&non_outermost_js); - __ mov(ip, Operand(StackFrame::INNER_JSENTRY_FRAME)); + __ mov(scratch, Operand(StackFrame::INNER_JSENTRY_FRAME)); __ bind(&cont); - __ push(ip); // frame-type + __ push(scratch); // frame-type // Jump to a faked try block that does the invoke, with a faked catch // block that sets the pending exception. @@ -642,12 +642,12 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, // field in the JSEnv and return a failure sentinel. Coming in here the // fp will be invalid because the PushStackHandler below sets it to 0 to // signal the existence of the JSEntry frame. - __ Move(ip, - ExternalReference::Create(IsolateAddressId::kPendingExceptionAddress, - masm->isolate())); + __ Move(scratch, + ExternalReference::Create( + IsolateAddressId::kPendingExceptionAddress, masm->isolate())); } - __ StoreP(r3, MemOperand(ip)); + __ StoreP(r3, MemOperand(scratch)); __ LoadRoot(r3, RootIndex::kException); __ b(&exit); @@ -679,16 +679,16 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, __ pop(r8); __ cmpi(r8, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME)); __ bne(&non_outermost_js_2); - __ mov(r9, Operand::Zero()); + __ mov(scratch, Operand::Zero()); __ Move(r8, js_entry_sp); - __ StoreP(r9, MemOperand(r8)); + __ StoreP(scratch, MemOperand(r8)); __ bind(&non_outermost_js_2); // Restore the top frame descriptors from the stack. __ pop(r6); - __ Move(ip, ExternalReference::Create( - IsolateAddressId::kCEntryFPAddress, masm->isolate())); - __ StoreP(r6, MemOperand(ip)); + __ Move(scratch, ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, + masm->isolate())); + __ StoreP(r6, MemOperand(scratch)); // Reset the stack to the callee saved registers. __ addi(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); @@ -894,13 +894,11 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, Register scratch1, Register scratch2, Register scratch3) { // ----------- S t a t e ------------- - // -- r0 : argument count (preserved for callee if needed, and caller) - // -- r3 : new target (preserved for callee if needed, and caller) - // -- r1 : target function (preserved for callee if needed, and caller) + // -- r6 : new target (preserved for callee if needed, and caller) + // -- r4 : target function (preserved for callee if needed, and caller) // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK( - !AreAliased(feedback_vector, r3, r4, r6, scratch1, scratch2, scratch3)); + DCHECK(!AreAliased(feedback_vector, r4, r6, scratch1, scratch2, scratch3)); Label optimized_code_slot_is_weak_ref, fallthrough; @@ -1084,6 +1082,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { FieldMemOperand(closure, JSFunction::kFeedbackCellOffset)); __ LoadP(feedback_vector, FieldMemOperand(feedback_vector, Cell::kValueOffset)); + + Label push_stack_frame; + // Check if feedback vector is valid. If valid, check for optimized code + // and update invocation count. Otherwise, setup the stack frame. + __ LoadP(r7, FieldMemOperand(feedback_vector, HeapObject::kMapOffset)); + __ LoadHalfWord(r7, FieldMemOperand(r7, Map::kInstanceTypeOffset)); + __ cmpi(r7, Operand(FEEDBACK_VECTOR_TYPE)); + __ bne(&push_stack_frame); + // Read off the optimized code slot in the feedback vector, and if there // is optimized code or an optimization marker, call that instead. MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r7, r9, r8); @@ -1102,6 +1109,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Open a frame scope to indicate that there is a frame on the stack. The // MANUAL indicates that the scope shouldn't actually generate code to set up // the frame (that is done below). + + __ bind(&push_stack_frame); + FrameScope frame_scope(masm, StackFrame::MANUAL); __ PushStandardFrame(closure); @@ -1109,12 +1119,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // 8-bit fields next to each other, so we could just optimize by writing a // 16-bit. These static asserts guard our assumption is valid. STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == - BytecodeArray::kOSRNestingLevelOffset + kCharSize); + BytecodeArray::kOsrNestingLevelOffset + kCharSize); STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); __ li(r8, Operand(0)); __ StoreHalfWord(r8, FieldMemOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kOSRNestingLevelOffset), + BytecodeArray::kOsrNestingLevelOffset), r0); // Load initial bytecode offset. @@ -1395,11 +1405,13 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { __ SmiUntag(kInterpreterBytecodeOffsetRegister); // Dispatch to the target bytecode. + UseScratchRegisterScope temps(masm); + Register scratch = temps.Acquire(); __ lbzx(ip, MemOperand(kInterpreterBytecodeArrayRegister, kInterpreterBytecodeOffsetRegister)); - __ ShiftLeftImm(ip, ip, Operand(kPointerSizeLog2)); + __ ShiftLeftImm(scratch, scratch, Operand(kPointerSizeLog2)); __ LoadPX(kJavaScriptCallCodeStartRegister, - MemOperand(kInterpreterDispatchTableRegister, ip)); + MemOperand(kInterpreterDispatchTableRegister, scratch)); __ Jump(kJavaScriptCallCodeStartRegister); } @@ -1526,13 +1538,17 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, __ LoadP( fp, MemOperand(sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); - __ Pop(ip); + // Load builtin index (stored as a Smi) and use it to get the builtin start + // address from the builtins table. + UseScratchRegisterScope temps(masm); + Register builtin = temps.Acquire(); + __ Pop(builtin); __ addi(sp, sp, Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); __ Pop(r0); __ mtlr(r0); - __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); - __ Jump(ip); + __ LoadEntryFromBuiltinIndex(builtin); + __ Jump(builtin); } } // namespace @@ -1702,14 +1718,15 @@ void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { // r3: actual number of arguments // r4: callable { + Register scratch = r6; Label loop; // Calculate the copy start address (destination). Copy end address is sp. __ add(r5, sp, r5); __ mtctr(r3); __ bind(&loop); - __ LoadP(ip, MemOperand(r5, -kPointerSize)); - __ StoreP(ip, MemOperand(r5)); + __ LoadP(scratch, MemOperand(r5, -kPointerSize)); + __ StoreP(scratch, MemOperand(r5)); __ subi(r5, r5, Operand(kPointerSize)); __ bdnz(&loop); // Adjust the actual number of arguments and remove the top element @@ -1891,7 +1908,7 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, // Check for stack overflow. Label stack_overflow; - Generate_StackOverflowCheck(masm, r7, ip, &stack_overflow); + Generate_StackOverflowCheck(masm, r7, scratch, &stack_overflow); // Push arguments onto the stack (thisArgument is already on the stack). { @@ -1902,12 +1919,12 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); __ mtctr(r7); __ bind(&loop); - __ LoadPU(ip, MemOperand(r5, kPointerSize)); - __ CompareRoot(ip, RootIndex::kTheHoleValue); + __ LoadPU(scratch, MemOperand(r5, kPointerSize)); + __ CompareRoot(scratch, RootIndex::kTheHoleValue); __ bne(&skip); - __ LoadRoot(ip, RootIndex::kUndefinedValue); + __ LoadRoot(scratch, RootIndex::kUndefinedValue); __ bind(&skip); - __ push(ip); + __ push(scratch); __ bdnz(&loop); __ bind(&no_args); __ add(r3, r3, r7); @@ -1953,8 +1970,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, // Check if we have an arguments adaptor frame below the function frame. Label arguments_adaptor, arguments_done; __ LoadP(r7, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ LoadP(ip, MemOperand(r7, CommonFrameConstants::kContextOrFrameTypeOffset)); - __ cmpi(ip, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); + __ LoadP(scratch, + MemOperand(r7, CommonFrameConstants::kContextOrFrameTypeOffset)); + __ cmpi(scratch, + Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); __ beq(&arguments_adaptor); { __ LoadP(r8, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); @@ -1988,9 +2007,9 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, __ add(r3, r3, r8); __ bind(&loop); { - __ ShiftLeftImm(ip, r8, Operand(kPointerSizeLog2)); - __ LoadPX(ip, MemOperand(r7, ip)); - __ push(ip); + __ ShiftLeftImm(scratch, r8, Operand(kPointerSizeLog2)); + __ LoadPX(scratch, MemOperand(r7, scratch)); + __ push(scratch); __ subi(r8, r8, Operand(1)); __ cmpi(r8, Operand::Zero()); __ bne(&loop); @@ -2134,10 +2153,11 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { // -- r7 : the number of [[BoundArguments]] // ----------------------------------- + Register scratch = r9; // Reserve stack space for the [[BoundArguments]]. { Label done; - __ mr(r9, sp); // preserve previous stack pointer + __ mr(scratch, sp); // preserve previous stack pointer __ ShiftLeftImm(r10, r7, Operand(kPointerSizeLog2)); __ sub(sp, sp, r10); // Check the stack for overflow. We are not trying to catch interruptions @@ -2146,7 +2166,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { __ CompareRoot(sp, RootIndex::kRealStackLimit); __ bgt(&done); // Signed comparison. // Restore the stack pointer. - __ mr(sp, r9); + __ mr(sp, scratch); { FrameScope scope(masm, StackFrame::MANUAL); __ EnterFrame(StackFrame::INTERNAL); @@ -2166,7 +2186,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { __ beq(&skip); __ mtctr(r3); __ bind(&loop); - __ LoadPX(r0, MemOperand(r9, r8)); + __ LoadPX(r0, MemOperand(scratch, r8)); __ StorePX(r0, MemOperand(sp, r8)); __ addi(r8, r8, Operand(kPointerSize)); __ bdnz(&loop); @@ -2201,9 +2221,9 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) { __ AssertBoundFunction(r4); // Patch the receiver to [[BoundThis]]. - __ LoadP(ip, FieldMemOperand(r4, JSBoundFunction::kBoundThisOffset)); + __ LoadP(r6, FieldMemOperand(r4, JSBoundFunction::kBoundThisOffset)); __ ShiftLeftImm(r0, r3, Operand(kPointerSizeLog2)); - __ StorePX(ip, MemOperand(sp, r0)); + __ StorePX(r6, MemOperand(sp, r0)); // Push the [[BoundArguments]] onto the stack. Generate_PushBoundArguments(masm); @@ -2388,7 +2408,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { __ cmpli(r5, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); __ beq(&dont_adapt_arguments); __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); - __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kFlagsOffset)); + __ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kFlagsOffset)); __ TestBitMask(r7, SharedFunctionInfo::IsSafeToSkipArgumentsAdaptorBit::kMask, r0); __ bne(&skip_adapt_arguments, cr0); @@ -2686,7 +2706,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, __ CompareRoot(r6, RootIndex::kTheHoleValue); // Cannot use check here as it attempts to generate call into runtime. __ beq(&okay); - __ stop("Unexpected pending exception"); + __ stop(); __ bind(&okay); } @@ -2961,13 +2981,22 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm, __ Move(scratch, thunk_ref); __ isel(eq, scratch, function_address, scratch); } else { - Label profiler_disabled; - Label end_profiler_check; - __ beq(&profiler_disabled); - __ Move(scratch, thunk_ref); - __ b(&end_profiler_check); - __ bind(&profiler_disabled); - __ mr(scratch, function_address); + Label profiler_enabled, end_profiler_check; + __ bne(&profiler_enabled); + __ Move(scratch, ExternalReference::address_of_runtime_stats_flag()); + __ lwz(scratch, MemOperand(scratch, 0)); + __ cmpi(scratch, Operand::Zero()); + __ bne(&profiler_enabled); + { + // Call the api function directly. + __ mr(scratch, function_address); + __ b(&end_profiler_check); + } + __ bind(&profiler_enabled); + { + // Additional parameter is the address of the actual callback. + __ Move(scratch, thunk_ref); + } __ bind(&end_profiler_check); } @@ -3264,6 +3293,8 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) { } void Builtins::Generate_DirectCEntry(MacroAssembler* masm) { + UseScratchRegisterScope temps(masm); + Register temp2 = temps.Acquire(); // Place the return address on the stack, making the call // GC safe. The RegExp backend also relies on this. __ mflr(r0); @@ -3271,11 +3302,11 @@ void Builtins::Generate_DirectCEntry(MacroAssembler* masm) { if (ABI_USES_FUNCTION_DESCRIPTORS && FLAG_embedded_builtins) { // AIX/PPC64BE Linux use a function descriptor; - __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(ip, kPointerSize)); - __ LoadP(ip, MemOperand(ip, 0)); // Instruction address + __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(temp2, kPointerSize)); + __ LoadP(temp2, MemOperand(temp2, 0)); // Instruction address } - __ Call(ip); // Call the C++ function. + __ Call(temp2); // Call the C++ function. __ LoadP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); __ mtlr(r0); __ blr(); diff --git a/deps/v8/src/builtins/proxy-constructor.tq b/deps/v8/src/builtins/proxy-constructor.tq index 178759b595..ad60c20e2c 100644 --- a/deps/v8/src/builtins/proxy-constructor.tq +++ b/deps/v8/src/builtins/proxy-constructor.tq @@ -6,17 +6,14 @@ namespace proxy { - extern macro ProxiesCodeStubAssembler::GetProxyConstructorJSNewTarget(): - Object; - // ES #sec-proxy-constructor // https://tc39.github.io/ecma262/#sec-proxy-constructor transitioning javascript builtin - ProxyConstructor(implicit context: Context)( - receiver: Object, target: Object, handler: Object): JSProxy { + ProxyConstructor( + js-implicit context: Context, receiver: Object, + newTarget: Object)(target: Object, handler: Object): JSProxy { try { // 1. If NewTarget is undefined, throw a TypeError exception. - const newTarget: Object = GetProxyConstructorJSNewTarget(); if (newTarget == Undefined) { ThrowTypeError(kConstructorNotFunction, 'Proxy'); } diff --git a/deps/v8/src/builtins/proxy-delete-property.tq b/deps/v8/src/builtins/proxy-delete-property.tq new file mode 100644 index 0000000000..759de766ef --- /dev/null +++ b/deps/v8/src/builtins/proxy-delete-property.tq @@ -0,0 +1,67 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-proxy-gen.h' + +namespace proxy { + + // ES #sec-proxy-object-internal-methods-and-internal-slots-delete-p + // https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-delete-p + transitioning builtin + ProxyDeleteProperty(implicit context: Context)( + proxy: JSProxy, name: Name, languageMode: LanguageMode): Object { + const kTrapName: constexpr string = 'deleteProperty'; + // 1. Assert: IsPropertyKey(P) is true. + assert(TaggedIsNotSmi(name)); + assert(IsName(name)); + assert(!IsPrivateSymbol(name)); + + try { + // 2. Let handler be O.[[ProxyHandler]]. + // 3. If handler is null, throw a TypeError exception. + // 4. Assert: Type(handler) is Object. + assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); + const handler = + Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; + + // 5. Let target be O.[[ProxyTarget]]. + const target = UnsafeCast<JSReceiver>(proxy.target); + + // 6. Let trap be ? GetMethod(handler, "deleteProperty"). + // 7. If trap is undefined, then (see 7.a below). + const trap: Callable = GetMethod(handler, kTrapName) + otherwise goto TrapUndefined(target); + + // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, + // « target, P »)). + const trapResult = Call(context, trap, handler, target, name); + + // 9. If booleanTrapResult is false, return false. + if (BranchIfToBooleanIsFalse(trapResult)) { + if (languageMode == SmiConstant(kStrict)) { + ThrowTypeError(kProxyTrapReturnedFalsishFor, kTrapName, name); + } + return False; + } + + // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). + // 11. If targetDesc is undefined, return true. + // 12. If targetDesc.[[Configurable]] is false, throw a TypeError + // exception. + // 13. Let extensibleTarget be ? IsExtensible(target). + // 14. If extensibleTarget is false, throw a TypeError exception. + CheckDeleteTrapResult(target, proxy, name); + + // 15. Return true. + return True; + } + label TrapUndefined(target: Object) { + // 7.a. Return ? target.[[Delete]](P). + return DeleteProperty(target, name, languageMode); + } + label ThrowProxyHandlerRevoked deferred { + ThrowTypeError(kProxyRevoked, kTrapName); + } + } +} diff --git a/deps/v8/src/builtins/proxy-get-property.tq b/deps/v8/src/builtins/proxy-get-property.tq index 0915a66d5f..bac07f550c 100644 --- a/deps/v8/src/builtins/proxy-get-property.tq +++ b/deps/v8/src/builtins/proxy-get-property.tq @@ -6,9 +6,8 @@ namespace proxy { - extern transitioning runtime - GetPropertyWithReceiver(implicit context: Context)(Object, Name, Object, Smi): - Object; + extern transitioning builtin GetPropertyWithReceiver( + implicit context: Context)(Object, Name, Object, Smi): Object; // ES #sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver // https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver @@ -16,36 +15,38 @@ namespace proxy { ProxyGetProperty(implicit context: Context)( proxy: JSProxy, name: Name, receiverValue: Object, onNonExistent: Smi): Object { + PerformStackCheck(); // 1. Assert: IsPropertyKey(P) is true. assert(TaggedIsNotSmi(name)); assert(IsName(name)); assert(!IsPrivateSymbol(name)); // 2. Let handler be O.[[ProxyHandler]]. - const handler: Object = proxy.handler; - // 3. If handler is null, throw a TypeError exception. - if (handler == Null) { - ThrowTypeError(kProxyRevoked, 'get'); - } - // 4. Assert: Type(handler) is Object. - const handlerJSReceiver = UnsafeCast<JSReceiver>(handler); + let handler: JSReceiver; + typeswitch (proxy.handler) { + case (Null): { + ThrowTypeError(kProxyRevoked, 'get'); + } + case (h: JSReceiver): { + handler = h; + } + } // 5. Let target be O.[[ProxyTarget]]. - const target = proxy.target; + const target = Cast<JSReceiver>(proxy.target) otherwise unreachable; // 6. Let trap be ? GetMethod(handler, "get"). // 7. If trap is undefined, then (see 7.a below). // 7.a. Return ? target.[[Get]](P, Receiver). - // TODO(mslekova): Introduce GetPropertyWithReceiver stub - const trap: Callable = GetMethod(handlerJSReceiver, 'get') + const trap: Callable = GetMethod(handler, 'get') otherwise return GetPropertyWithReceiver( target, name, receiverValue, onNonExistent); // 8. Let trapResult be ? Call(trap, handler, « target, P, Receiver »). const trapResult = - Call(context, trap, handlerJSReceiver, target, name, receiverValue); + Call(context, trap, handler, target, name, receiverValue); // 9. Let targetDesc be ? target.[[GetOwnProperty]](P). // 10. If targetDesc is not undefined and targetDesc.[[Configurable]] is @@ -58,6 +59,7 @@ namespace proxy { // is undefined, then // i. If trapResult is not undefined, throw a TypeError exception. // 11. Return trapResult. - return CheckGetSetTrapResult(target, proxy, name, trapResult, kProxyGet); + CheckGetSetTrapResult(target, proxy, name, trapResult, kProxyGet); + return trapResult; } } diff --git a/deps/v8/src/builtins/proxy-get-prototype-of.tq b/deps/v8/src/builtins/proxy-get-prototype-of.tq new file mode 100644 index 0000000000..2418eaf423 --- /dev/null +++ b/deps/v8/src/builtins/proxy-get-prototype-of.tq @@ -0,0 +1,70 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-proxy-gen.h' + +namespace proxy { + + // ES #sec-proxy-object-internal-methods-and-internal-slots-isextensible + // https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-isextensible + transitioning builtin + ProxyGetPrototypeOf(implicit context: Context)(proxy: JSProxy): Object { + PerformStackCheck(); + const kTrapName: constexpr string = 'getPrototypeOf'; + try { + // 1. Let handler be O.[[ProxyHandler]]. + // 2. If handler is null, throw a TypeError exception. + // 3. Assert: Type(handler) is Object. + assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); + const handler = + Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; + + // 4. Let target be O.[[ProxyTarget]]. + const target = proxy.target; + + // 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). + // 6. If trap is undefined, then (see 6.a below). + const trap: Callable = GetMethod(handler, kTrapName) + otherwise goto TrapUndefined(target); + + // 7. Let handlerProto be ? Call(trap, handler, « target »). + const handlerProto = Call(context, trap, handler, target); + + // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError + // exception. + if (!Is<JSReceiver>(handlerProto)) { + goto ThrowProxyGetPrototypeOfInvalid; + } + + // 9. Let extensibleTarget be ? IsExtensible(target). + // 10. If extensibleTarget is true, return handlerProto. + const extensibleTarget: Object = object::ObjectIsExtensible(target); + assert(extensibleTarget == True || extensibleTarget == False); + if (extensibleTarget == True) { + return handlerProto; + } + + // 11. Let targetProto be ? target.[[GetPrototypeOf]](). + const targetProto = object::ObjectGetPrototypeOf(target); + + // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError + // exception. + // 13. Return handlerProto. + if (BranchIfSameValue(targetProto, handlerProto)) { + return handlerProto; + } + ThrowTypeError(kProxyGetPrototypeOfNonExtensible); + } + label TrapUndefined(target: Object) { + // 6.a. Return ? target.[[GetPrototypeOf]](). + return object::ObjectGetPrototypeOf(target); + } + label ThrowProxyHandlerRevoked deferred { + ThrowTypeError(kProxyRevoked, kTrapName); + } + label ThrowProxyGetPrototypeOfInvalid deferred { + ThrowTypeError(kProxyGetPrototypeOfInvalid); + } + } +} diff --git a/deps/v8/src/builtins/proxy-has-property.tq b/deps/v8/src/builtins/proxy-has-property.tq index ab3898a9c7..ee394c5d84 100644 --- a/deps/v8/src/builtins/proxy-has-property.tq +++ b/deps/v8/src/builtins/proxy-has-property.tq @@ -22,11 +22,12 @@ namespace proxy { // 2. Let handler be O.[[ProxyHandler]]. // 3. If handler is null, throw a TypeError exception. // 4. Assert: Type(handler) is Object. + assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); const handler = Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; // 5. Let target be O.[[ProxyTarget]]. - const target = proxy.target; + const target = Cast<JSReceiver>(proxy.target) otherwise unreachable; // 6. Let trap be ? GetMethod(handler, "has"). // 7. If trap is undefined, then (see 7.a below). @@ -42,7 +43,8 @@ namespace proxy { if (BranchIfToBooleanIsTrue(trapResult)) { return True; } - return CheckHasTrapResult(target, proxy, name); + CheckHasTrapResult(target, proxy, name); + return False; } label TrapUndefined(target: Object) { // 7.a. Return ? target.[[HasProperty]](P). diff --git a/deps/v8/src/builtins/proxy-is-extensible.tq b/deps/v8/src/builtins/proxy-is-extensible.tq new file mode 100644 index 0000000000..82f4a5b955 --- /dev/null +++ b/deps/v8/src/builtins/proxy-is-extensible.tq @@ -0,0 +1,56 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-proxy-gen.h' + +namespace proxy { + + // ES #sec-proxy-object-internal-methods-and-internal-slots-isextensible + // https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-isextensible + transitioning builtin ProxyIsExtensible(implicit context: + Context)(proxy: JSProxy): Object { + PerformStackCheck(); + const kTrapName: constexpr string = 'isExtensible'; + try { + // 1. Let handler be O.[[ProxyHandler]]. + // 2. If handler is null, throw a TypeError exception. + // 3. Assert: Type(handler) is Object. + assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); + const handler = + Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; + + // 4. Let target be O.[[ProxyTarget]]. + const target = proxy.target; + + // 5. Let trap be ? GetMethod(handler, "isExtensible"). + // 6. If trap is undefined, then (see 6.a below). + const trap: Callable = GetMethod(handler, kTrapName) + otherwise goto TrapUndefined(target); + + // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « + // target»)). + const trapResult = ToBoolean(Call(context, trap, handler, target)); + + // 8. Let targetResult be ? IsExtensible(target). + const targetResult: bool = ToBoolean(object::ObjectIsExtensible(target)); + + // 9. If SameValue(booleanTrapResult, targetResult) is false, throw a + // TypeError exception. + if (trapResult != targetResult) { + ThrowTypeError( + kProxyIsExtensibleInconsistent, + SelectBooleanConstant(targetResult)); + } + // 10. Return booleanTrapResult. + return SelectBooleanConstant(trapResult); + } + label TrapUndefined(target: Object) { + // 6.a. Return ? IsExtensible(target). + return object::ObjectIsExtensible(target); + } + label ThrowProxyHandlerRevoked deferred { + ThrowTypeError(kProxyRevoked, kTrapName); + } + } +} diff --git a/deps/v8/src/builtins/proxy-prevent-extensions.tq b/deps/v8/src/builtins/proxy-prevent-extensions.tq new file mode 100644 index 0000000000..6d5d2569fb --- /dev/null +++ b/deps/v8/src/builtins/proxy-prevent-extensions.tq @@ -0,0 +1,66 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-proxy-gen.h' + +namespace proxy { + + // ES #sec-proxy-object-internal-methods-and-internal-slots-preventextensions + // https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-preventextensions + transitioning builtin + ProxyPreventExtensions(implicit context: Context)( + proxy: JSProxy, doThrow: Boolean): Object { + PerformStackCheck(); + const kTrapName: constexpr string = 'preventExtensions'; + try { + // 1. Let handler be O.[[ProxyHandler]]. + // 2. If handler is null, throw a TypeError exception. + // 3. Assert: Type(handler) is Object. + assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); + const handler = + Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; + + // 4. Let target be O.[[ProxyTarget]]. + const target = proxy.target; + + // 5. Let trap be ? GetMethod(handler, "preventExtensions"). + // 6. If trap is undefined, then (see 6.a below). + const trap: Callable = GetMethod(handler, kTrapName) + otherwise goto TrapUndefined(target); + + // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « + // target»)). + const trapResult = Call(context, trap, handler, target); + + // 8. If booleanTrapResult is true, then + // 8.a. Let extensibleTarget be ? IsExtensible(target). + // 8.b If extensibleTarget is true, throw a TypeError exception. + if (BranchIfToBooleanIsTrue(trapResult)) { + const extensibleTarget: Object = object::ObjectIsExtensible(target); + assert(extensibleTarget == True || extensibleTarget == False); + if (extensibleTarget == True) { + ThrowTypeError(kProxyPreventExtensionsExtensible); + } + } else { + if (doThrow == True) { + ThrowTypeError(kProxyTrapReturnedFalsish, kTrapName); + } + return False; + } + + // 9. Return booleanTrapResult. + return True; + } + label TrapUndefined(target: Object) { + // 6.a. Return ? target.[[PreventExtensions]](). + if (doThrow == True) { + return object::ObjectPreventExtensionsThrow(target); + } + return object::ObjectPreventExtensionsDontThrow(target); + } + label ThrowProxyHandlerRevoked deferred { + ThrowTypeError(kProxyRevoked, kTrapName); + } + } +} // namespace proxy diff --git a/deps/v8/src/builtins/proxy-revocable.tq b/deps/v8/src/builtins/proxy-revocable.tq index 695f005c9b..b09baab9cf 100644 --- a/deps/v8/src/builtins/proxy-revocable.tq +++ b/deps/v8/src/builtins/proxy-revocable.tq @@ -7,17 +7,13 @@ namespace proxy { extern macro ProxiesCodeStubAssembler::AllocateProxyRevokeFunction( - Object, Object): JSFunction; - macro AllocateProxyRevokeFunction(implicit context: Context)(proxy: JSProxy): - JSFunction { - return AllocateProxyRevokeFunction(proxy, context); - } + implicit context: Context)(JSProxy): JSFunction; // Proxy.revocable(target, handler) // https://tc39.github.io/ecma262/#sec-proxy.revocable transitioning javascript builtin ProxyRevocable( - context: Context, receiver: Object, target: Object, + context: Context, _receiver: Object, target: Object, handler: Object): JSProxyRevocableResult { try { const targetJSReceiver = diff --git a/deps/v8/src/builtins/proxy-revoke.tq b/deps/v8/src/builtins/proxy-revoke.tq index 400f586b21..d89b54077a 100644 --- a/deps/v8/src/builtins/proxy-revoke.tq +++ b/deps/v8/src/builtins/proxy-revoke.tq @@ -9,7 +9,7 @@ namespace proxy { // Proxy Revocation Functions // https://tc39.github.io/ecma262/#sec-proxy-revocation-functions transitioning javascript builtin - ProxyRevoke(implicit context: Context)(): Undefined { + ProxyRevoke(js-implicit context: Context)(): Undefined { // 1. Let p be F.[[RevocableProxy]]. const proxyObject: Object = context[PROXY_SLOT]; diff --git a/deps/v8/src/builtins/proxy-set-property.tq b/deps/v8/src/builtins/proxy-set-property.tq index 72181e08a8..d0411a8e89 100644 --- a/deps/v8/src/builtins/proxy-set-property.tq +++ b/deps/v8/src/builtins/proxy-set-property.tq @@ -30,21 +30,20 @@ namespace proxy { return Undefined; } - // 2. Let handler be O.[[ProxyHandler]]. - const handler: Object = proxy.handler; - try { + // 2. Let handler be O.[[ProxyHandler]]. // 3. If handler is null, throw a TypeError exception. // 4. Assert: Type(handler) is Object. - const handlerJSReceiver = - Cast<JSReceiver>(handler) otherwise ThrowProxyHandlerRevoked; + assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); + const handler = + Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; // 5. Let target be O.[[ProxyTarget]]. - const target = proxy.target; + const target = UnsafeCast<JSReceiver>(proxy.target); // 6. Let trap be ? GetMethod(handler, "set"). // 7. If trap is undefined, then (see 7.a below). - const trap: Callable = GetMethod(handlerJSReceiver, 'set') + const trap: Callable = GetMethod(handler, 'set') otherwise goto TrapUndefined(target); // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, @@ -61,11 +60,11 @@ namespace proxy { // i. If targetDesc.[[Set]] is undefined, throw a TypeError // exception. // 12. Return true. - const trapResult = Call( - context, trap, handlerJSReceiver, target, name, value, receiverValue); + const trapResult = + Call(context, trap, handler, target, name, value, receiverValue); if (BranchIfToBooleanIsTrue(trapResult)) { - return CheckGetSetTrapResult( - target, proxy, name, trapResult, kProxySet); + CheckGetSetTrapResult(target, proxy, name, value, kProxySet); + return value; } ThrowTypeErrorIfStrict( SmiConstant(kProxyTrapReturnedFalsishFor), 'set', name); @@ -77,7 +76,6 @@ namespace proxy { return value; } label ThrowProxyHandlerRevoked deferred { - assert(handler == Null); ThrowTypeError(kProxyRevoked, 'set'); } } diff --git a/deps/v8/src/builtins/proxy-set-prototype-of.tq b/deps/v8/src/builtins/proxy-set-prototype-of.tq new file mode 100644 index 0000000000..bbd99be411 --- /dev/null +++ b/deps/v8/src/builtins/proxy-set-prototype-of.tq @@ -0,0 +1,77 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-proxy-gen.h' + +namespace proxy { + + // ES #sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v + // https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v + transitioning builtin + ProxySetPrototypeOf(implicit context: Context)( + proxy: JSProxy, proto: Object, doThrow: Boolean): Object { + PerformStackCheck(); + const kTrapName: constexpr string = 'setPrototypeOf'; + try { + // 1. Assert: Either Type(V) is Object or Type(V) is Null. + assert(proto == Null || Is<JSReceiver>(proto)); + + // 2. Let handler be O.[[ProxyHandler]]. + // 3. If handler is null, throw a TypeError exception. + // 4. Assert: Type(handler) is Object. + assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler)); + const handler = + Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked; + + // 5. Let target be O.[[ProxyTarget]]. + const target = proxy.target; + + // 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + // 7. If trap is undefined, then (see 7.a below). + const trap: Callable = GetMethod(handler, kTrapName) + otherwise goto TrapUndefined(target, proto); + + // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V + // »)). + const trapResult = Call(context, trap, handler, target, proto); + + // 9. If booleanTrapResult is false, return false. + if (BranchIfToBooleanIsFalse(trapResult)) { + if (doThrow == True) { + ThrowTypeError(kProxyTrapReturnedFalsishFor, kTrapName); + } + return False; + } + + // 10. Let extensibleTarget be ? IsExtensible(target). + // 11. If extensibleTarget is true, return true. + const extensibleTarget: Object = object::ObjectIsExtensible(target); + assert(extensibleTarget == True || extensibleTarget == False); + if (extensibleTarget == True) { + return True; + } + + // 12. Let targetProto be ? target.[[GetPrototypeOf]](). + const targetProto = object::ObjectGetPrototypeOf(target); + + // 13. If SameValue(V, targetProto) is false, throw a TypeError + // exception. + // 14. Return true. + if (BranchIfSameValue(proto, targetProto)) { + return True; + } + ThrowTypeError(kProxySetPrototypeOfNonExtensible); + } + label TrapUndefined(target: Object, proto: Object) { + // 7.a. Return ? target.[[SetPrototypeOf]](). + if (doThrow == True) { + return object::ObjectSetPrototypeOfThrow(target, proto); + } + return object::ObjectSetPrototypeOfDontThrow(target, proto); + } + label ThrowProxyHandlerRevoked deferred { + ThrowTypeError(kProxyRevoked, kTrapName); + } + } +} diff --git a/deps/v8/src/builtins/proxy.tq b/deps/v8/src/builtins/proxy.tq index 16bba85292..d95def5d0e 100644 --- a/deps/v8/src/builtins/proxy.tq +++ b/deps/v8/src/builtins/proxy.tq @@ -7,25 +7,23 @@ namespace proxy { extern macro ProxiesCodeStubAssembler::AllocateProxy( - JSReceiver, JSReceiver, Context): JSProxy; - macro AllocateProxy(implicit context: Context)( - target: JSReceiver, handler: JSReceiver): JSProxy { - return AllocateProxy(target, handler, context); - } + implicit context: Context)(JSReceiver, JSReceiver): JSProxy; macro IsRevokedProxy(implicit context: Context)(o: JSReceiver): bool { const proxy: JSProxy = Cast<JSProxy>(o) otherwise return false; - const handler: JSReceiver = - Cast<JSReceiver>(proxy.handler) otherwise return true; + Cast<JSReceiver>(proxy.handler) otherwise return true; return false; } extern transitioning macro ProxiesCodeStubAssembler::CheckGetSetTrapResult( implicit context: - Context)(Object, JSProxy, Name, Object, constexpr int31): Object; + Context)(JSReceiver, JSProxy, Name, Object, constexpr int31); + + extern transitioning macro ProxiesCodeStubAssembler::CheckDeleteTrapResult( + implicit context: Context)(JSReceiver, JSProxy, Name); extern transitioning macro ProxiesCodeStubAssembler::CheckHasTrapResult( - implicit context: Context)(Object, JSProxy, Name): Object; + implicit context: Context)(JSReceiver, JSProxy, Name); const kProxyNonObject: constexpr MessageTemplate generates 'MessageTemplate::kProxyNonObject'; @@ -37,6 +35,20 @@ namespace proxy { generates 'MessageTemplate::kProxyTrapReturnedFalsishFor'; const kProxyPrivate: constexpr MessageTemplate generates 'MessageTemplate::kProxyPrivate'; + const kProxyIsExtensibleInconsistent: constexpr MessageTemplate + generates 'MessageTemplate::kProxyIsExtensibleInconsistent'; + const kProxyPreventExtensionsExtensible: constexpr MessageTemplate + generates 'MessageTemplate::kProxyPreventExtensionsExtensible'; + const kProxyTrapReturnedFalsish: constexpr MessageTemplate + generates 'MessageTemplate::kProxyTrapReturnedFalsish'; + const kProxyGetPrototypeOfInvalid: constexpr MessageTemplate + generates 'MessageTemplate::kProxyGetPrototypeOfInvalid'; + const kProxyGetPrototypeOfNonExtensible: constexpr MessageTemplate + generates 'MessageTemplate::kProxyGetPrototypeOfNonExtensible'; + const kProxySetPrototypeOfNonExtensible: constexpr MessageTemplate + generates 'MessageTemplate::kProxySetPrototypeOfNonExtensible'; + const kProxyDeletePropertyNonExtensible: constexpr MessageTemplate + generates 'MessageTemplate::kProxyDeletePropertyNonExtensible'; const kProxyGet: constexpr int31 generates 'JSProxy::AccessKind::kGet'; diff --git a/deps/v8/src/builtins/reflect.tq b/deps/v8/src/builtins/reflect.tq new file mode 100644 index 0000000000..4c25e8338f --- /dev/null +++ b/deps/v8/src/builtins/reflect.tq @@ -0,0 +1,82 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace reflect { + + const kCalledOnNonObject: constexpr MessageTemplate + generates 'MessageTemplate::kCalledOnNonObject'; + + // ES6 section 26.1.10 Reflect.isExtensible + transitioning javascript builtin ReflectIsExtensible( + js-implicit context: Context)(_receiver: Object, object: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) + otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.isExtensible'); + return object::ObjectIsExtensible(objectJSReceiver); + } + + // ES6 section 26.1.12 Reflect.preventExtensions + transitioning javascript builtin ReflectPreventExtensions( + js-implicit context: Context)(_receiver: Object, object: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) + otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.preventExtensions'); + return object::ObjectPreventExtensionsDontThrow(objectJSReceiver); + } + + // ES6 section 26.1.8 Reflect.getPrototypeOf + transitioning javascript builtin ReflectGetPrototypeOf( + js-implicit context: Context)(_receiver: Object, object: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) + otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.getPrototypeOf'); + return object::JSReceiverGetPrototypeOf(objectJSReceiver); + } + + // ES6 section 26.1.14 Reflect.setPrototypeOf + transitioning javascript builtin ReflectSetPrototypeOf( + js-implicit context: + Context)(_receiver: Object, object: Object, proto: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) + otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.setPrototypeOf'); + if (proto == Null || Is<JSReceiver>(proto)) { + return object::ObjectSetPrototypeOfDontThrow(objectJSReceiver, proto); + } + ThrowTypeError(kProtoObjectOrNull, proto); + } + + extern transitioning builtin ToName(implicit context: Context)(Object): Name; + type OnNonExistent constexpr 'OnNonExistent'; + const kReturnUndefined: constexpr OnNonExistent + generates 'OnNonExistent::kReturnUndefined'; + extern macro SmiConstant(constexpr OnNonExistent): Smi; + extern transitioning builtin GetPropertyWithReceiver( + implicit context: Context)(Object, Name, Object, Smi): Object; + + // ES6 section 26.1.6 Reflect.get + transitioning javascript builtin + ReflectGet(js-implicit context: Context)(...arguments): Object { + const length = arguments.length; + const object: Object = length > 0 ? arguments[0] : Undefined; + const objectJSReceiver = Cast<JSReceiver>(object) + otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.get'); + const propertyKey: Object = length > 1 ? arguments[1] : Undefined; + const name: Name = ToName(propertyKey); + const receiver: Object = length > 2 ? arguments[2] : objectJSReceiver; + return GetPropertyWithReceiver( + objectJSReceiver, name, receiver, SmiConstant(kReturnUndefined)); + } + + // ES6 section 26.1.4 Reflect.deleteProperty + transitioning javascript builtin ReflectDeleteProperty( + js-implicit context: + Context)(_receiver: Object, object: Object, key: Object): Object { + const objectJSReceiver = Cast<JSReceiver>(object) + otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.deleteProperty'); + const name: Name = ToName(key); + if (IsPrivateSymbol(name)) { + return DeleteProperty(objectJSReceiver, name, kSloppy); + } + const proxy = Cast<JSProxy>(objectJSReceiver) + otherwise return DeleteProperty(objectJSReceiver, name, kSloppy); + return proxy::ProxyDeleteProperty(proxy, name, kSloppy); + } +} // namespace reflect diff --git a/deps/v8/src/builtins/regexp-replace.tq b/deps/v8/src/builtins/regexp-replace.tq index 9b95f99f41..cb0038c6b6 100644 --- a/deps/v8/src/builtins/regexp-replace.tq +++ b/deps/v8/src/builtins/regexp-replace.tq @@ -22,7 +22,7 @@ namespace regexp_replace { String, JSRegExp, Callable): String; extern macro - RegExpBuiltinsAssembler::AdvanceStringIndexFast(String, Number, bool): Smi; + RegExpBuiltinsAssembler::AdvanceStringIndexFast(String, Smi, bool): Smi; extern macro RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResultFast( implicit context: Context)(JSReceiver, String): @@ -72,8 +72,7 @@ namespace regexp_replace { transitioning macro RegExpReplaceCallableWithExplicitCaptures(implicit context: Context)( - matchesElements: FixedArray, matchesLength: intptr, string: String, - replaceFn: Callable) { + matchesElements: FixedArray, matchesLength: intptr, replaceFn: Callable) { for (let i: intptr = 0; i < matchesLength; i++) { const elArray = Cast<JSArray>(matchesElements.objects[i]) otherwise continue; @@ -124,7 +123,7 @@ namespace regexp_replace { matchesElements, matchesLengthInt, string, replaceFn); } else { RegExpReplaceCallableWithExplicitCaptures( - matchesElements, matchesLengthInt, string, replaceFn); + matchesElements, matchesLengthInt, replaceFn); } return StringBuilderConcat(matches, matchesLength, string); @@ -138,7 +137,7 @@ namespace regexp_replace { let result: String = kEmptyString; let lastMatchEnd: Smi = 0; let unicode: bool = false; - let replaceLength: Smi = replaceString.length_smi; + const replaceLength: Smi = replaceString.length_smi; const global: bool = regexp.global; if (global) { @@ -209,7 +208,7 @@ namespace regexp_replace { } transitioning javascript builtin RegExpPrototypeReplace( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { const methodName: constexpr string = 'RegExp.prototype.@@replace'; // RegExpPrototypeReplace is a bit of a beast - a summary of dispatch logic: diff --git a/deps/v8/src/builtins/s390/builtins-s390.cc b/deps/v8/src/builtins/s390/builtins-s390.cc index bf8c0cb68a..854f31cece 100644 --- a/deps/v8/src/builtins/s390/builtins-s390.cc +++ b/deps/v8/src/builtins/s390/builtins-s390.cc @@ -60,24 +60,20 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) { static void GenerateTailCallToReturnedCode(MacroAssembler* masm, Runtime::FunctionId function_id) { // ----------- S t a t e ------------- - // -- r2 : argument count (preserved for callee) // -- r3 : target function (preserved for callee) // -- r5 : new target (preserved for callee) // ----------------------------------- { FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - // Push the number of arguments to the callee. // Push a copy of the target function and the new target. // Push function as parameter to the runtime call. - __ SmiTag(r2); - __ Push(r2, r3, r5, r3); + __ Push(r3, r5, r3); __ CallRuntime(function_id, 1); __ LoadRR(r4, r2); // Restore target function and new target. - __ Pop(r2, r3, r5); - __ SmiUntag(r2); + __ Pop(r3, r5); } static_assert(kJavaScriptCallCodeStartRegister == r4, "ABI mismatch"); __ JumpCodeObject(r4); @@ -110,6 +106,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { // -- sp[...]: constructor arguments // ----------------------------------- + Register scratch = r4; Label stack_overflow; Generate_StackOverflowCheck(masm, r2, r7, &stack_overflow); @@ -138,13 +135,13 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { // sp[2]: number of arguments (smi-tagged) Label loop, no_args; __ beq(&no_args); - __ ShiftLeftP(ip, r2, Operand(kPointerSizeLog2)); - __ SubP(sp, sp, ip); + __ ShiftLeftP(scratch, r2, Operand(kPointerSizeLog2)); + __ SubP(sp, sp, scratch); __ LoadRR(r1, r2); __ bind(&loop); - __ lay(ip, MemOperand(ip, -kPointerSize)); - __ LoadP(r0, MemOperand(ip, r6)); - __ StoreP(r0, MemOperand(ip, sp)); + __ lay(scratch, MemOperand(scratch, -kPointerSize)); + __ LoadP(r0, MemOperand(scratch, r6)); + __ StoreP(r0, MemOperand(scratch, sp)); __ BranchOnCount(r1, &loop); __ bind(&no_args); @@ -159,15 +156,15 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { // Restore context from the frame. __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); // Restore smi-tagged arguments count from the frame. - __ LoadP(r3, MemOperand(fp, ConstructFrameConstants::kLengthOffset)); + __ LoadP(scratch, MemOperand(fp, ConstructFrameConstants::kLengthOffset)); // Leave construct frame. } // Remove caller arguments from the stack and return. STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); - __ SmiToPtrArrayOffset(r3, r3); - __ AddP(sp, sp, r3); + __ SmiToPtrArrayOffset(scratch, scratch); + __ AddP(sp, sp, scratch); __ AddP(sp, sp, Operand(kPointerSize)); __ Ret(); @@ -296,13 +293,13 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { __ ltgr(r2, r2); __ beq(&no_args); - __ ShiftLeftP(ip, r2, Operand(kPointerSizeLog2)); - __ SubP(sp, sp, ip); + __ ShiftLeftP(r8, r2, Operand(kPointerSizeLog2)); + __ SubP(sp, sp, r8); __ LoadRR(r1, r2); __ bind(&loop); - __ lay(ip, MemOperand(ip, -kPointerSize)); - __ LoadP(r0, MemOperand(ip, r6)); - __ StoreP(r0, MemOperand(ip, sp)); + __ lay(r8, MemOperand(r8, -kPointerSize)); + __ LoadP(r0, MemOperand(r8, r6)); + __ StoreP(r0, MemOperand(r8, sp)); __ BranchOnCount(r1, &loop); __ bind(&no_args); @@ -409,11 +406,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { // Flood function if we are stepping. Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator; Label stepping_prepared; + Register scratch = r7; + ExternalReference debug_hook = ExternalReference::debug_hook_on_function_call_address(masm->isolate()); - __ Move(ip, debug_hook); - __ LoadB(ip, MemOperand(ip)); - __ CmpSmiLiteral(ip, Smi::zero(), r0); + __ Move(scratch, debug_hook); + __ LoadB(scratch, MemOperand(scratch)); + __ CmpSmiLiteral(scratch, Smi::zero(), r0); __ bne(&prepare_step_in_if_stepping); // Flood function if we need to continue stepping in the suspended generator. @@ -421,9 +420,9 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { ExternalReference debug_suspended_generator = ExternalReference::debug_suspended_generator_address(masm->isolate()); - __ Move(ip, debug_suspended_generator); - __ LoadP(ip, MemOperand(ip)); - __ CmpP(ip, r3); + __ Move(scratch, debug_suspended_generator); + __ LoadP(scratch, MemOperand(scratch)); + __ CmpP(scratch, r3); __ beq(&prepare_step_in_suspended_generator); __ bind(&stepping_prepared); @@ -434,8 +433,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { __ blt(&stack_overflow); // Push receiver. - __ LoadP(ip, FieldMemOperand(r3, JSGeneratorObject::kReceiverOffset)); - __ Push(ip); + __ LoadP(scratch, FieldMemOperand(r3, JSGeneratorObject::kReceiverOffset)); + __ Push(scratch); // ----------- S t a t e ------------- // -- r3 : the JSGeneratorObject to resume @@ -626,6 +625,9 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, IsolateAddressId::kCEntryFPAddress, masm->isolate())); __ LoadP(r6, MemOperand(r6)); __ StoreMultipleP(r6, r9, MemOperand(sp, kPointerSize)); + + Register scrach = r8; + // Set up frame pointer for the frame to be pushed. // Need to add kPointerSize, because sp has one extra // frame already for the frame type being pushed later. @@ -642,17 +644,17 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, masm->isolate()); __ Move(r7, js_entry_sp); - __ LoadAndTestP(r8, MemOperand(r7)); + __ LoadAndTestP(scrach, MemOperand(r7)); __ bne(&non_outermost_js, Label::kNear); __ StoreP(fp, MemOperand(r7)); - __ Load(ip, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME)); + __ Load(scrach, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME)); Label cont; __ b(&cont, Label::kNear); __ bind(&non_outermost_js); - __ Load(ip, Operand(StackFrame::INNER_JSENTRY_FRAME)); + __ Load(scrach, Operand(StackFrame::INNER_JSENTRY_FRAME)); __ bind(&cont); - __ StoreP(ip, MemOperand(sp)); // frame-type + __ StoreP(scrach, MemOperand(sp)); // frame-type // Jump to a faked try block that does the invoke, with a faked catch // block that sets the pending exception. @@ -668,10 +670,11 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, // field in the JSEnv and return a failure sentinel. Coming in here the // fp will be invalid because the PushStackHandler below sets it to 0 to // signal the existence of the JSEntry frame. - __ Move(ip, ExternalReference::Create( - IsolateAddressId::kPendingExceptionAddress, masm->isolate())); + __ Move(scrach, + ExternalReference::Create(IsolateAddressId::kPendingExceptionAddress, + masm->isolate())); - __ StoreP(r2, MemOperand(ip)); + __ StoreP(r2, MemOperand(scrach)); __ LoadRoot(r2, RootIndex::kException); __ b(&exit, Label::kNear); @@ -704,16 +707,16 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, __ pop(r7); __ CmpP(r7, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME)); __ bne(&non_outermost_js_2, Label::kNear); - __ mov(r8, Operand::Zero()); + __ mov(scrach, Operand::Zero()); __ Move(r7, js_entry_sp); - __ StoreP(r8, MemOperand(r7)); + __ StoreP(scrach, MemOperand(r7)); __ bind(&non_outermost_js_2); // Restore the top frame descriptors from the stack. __ pop(r5); - __ Move(ip, ExternalReference::Create( - IsolateAddressId::kCEntryFPAddress, masm->isolate())); - __ StoreP(r5, MemOperand(ip)); + __ Move(scrach, ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, + masm->isolate())); + __ StoreP(r5, MemOperand(scrach)); // Reset the stack to the callee saved registers. __ lay(sp, MemOperand(sp, -EntryFrameConstants::kCallerFPOffset)); @@ -949,13 +952,11 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, Register scratch1, Register scratch2, Register scratch3) { // ----------- S t a t e ------------- - // -- r0 : argument count (preserved for callee if needed, and caller) - // -- r3 : new target (preserved for callee if needed, and caller) - // -- r1 : target function (preserved for callee if needed, and caller) + // -- r5 : new target (preserved for callee if needed, and caller) + // -- r3 : target function (preserved for callee if needed, and caller) // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK( - !AreAliased(feedback_vector, r2, r3, r5, scratch1, scratch2, scratch3)); + DCHECK(!AreAliased(feedback_vector, r3, r5, scratch1, scratch2, scratch3)); Label optimized_code_slot_is_weak_ref, fallthrough; @@ -1140,6 +1141,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { FieldMemOperand(closure, JSFunction::kFeedbackCellOffset)); __ LoadP(feedback_vector, FieldMemOperand(feedback_vector, Cell::kValueOffset)); + + Label push_stack_frame; + // Check if feedback vector is valid. If valid, check for optimized code + // and update invocation count. Otherwise, setup the stack frame. + __ LoadP(r6, FieldMemOperand(feedback_vector, HeapObject::kMapOffset)); + __ LoadLogicalHalfWordP(r6, FieldMemOperand(r6, Map::kInstanceTypeOffset)); + __ CmpP(r6, Operand(FEEDBACK_VECTOR_TYPE)); + __ bne(&push_stack_frame); + // Read off the optimized code slot in the feedback vector, and if there // is optimized code or an optimization marker, call that instead. MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r6, r8, r7); @@ -1154,6 +1164,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Open a frame scope to indicate that there is a frame on the stack. The // MANUAL indicates that the scope shouldn't actually generate code to set up // the frame (that is done below). + __ bind(&push_stack_frame); FrameScope frame_scope(masm, StackFrame::MANUAL); __ PushStandardFrame(closure); @@ -1161,12 +1172,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // 8-bit fields next to each other, so we could just optimize by writing a // 16-bit. These static asserts guard our assumption is valid. STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == - BytecodeArray::kOSRNestingLevelOffset + kCharSize); + BytecodeArray::kOsrNestingLevelOffset + kCharSize); STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); __ lghi(r1, Operand(0)); __ StoreHalfWord(r1, FieldMemOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kOSRNestingLevelOffset), + BytecodeArray::kOsrNestingLevelOffset), r0); // Load the initial bytecode offset. @@ -1447,11 +1458,13 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { __ SmiUntag(kInterpreterBytecodeOffsetRegister); // Dispatch to the target bytecode. - __ LoadlB(ip, MemOperand(kInterpreterBytecodeArrayRegister, - kInterpreterBytecodeOffsetRegister)); - __ ShiftLeftP(ip, ip, Operand(kPointerSizeLog2)); + UseScratchRegisterScope temps(masm); + Register scratch = temps.Acquire(); + __ LoadlB(scratch, MemOperand(kInterpreterBytecodeArrayRegister, + kInterpreterBytecodeOffsetRegister)); + __ ShiftLeftP(scratch, scratch, Operand(kPointerSizeLog2)); __ LoadP(kJavaScriptCallCodeStartRegister, - MemOperand(kInterpreterDispatchTableRegister, ip)); + MemOperand(kInterpreterDispatchTableRegister, scratch)); __ Jump(kJavaScriptCallCodeStartRegister); } @@ -1578,13 +1591,17 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, __ LoadP( fp, MemOperand(sp, BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); - __ Pop(ip); + // Load builtin index (stored as a Smi) and use it to get the builtin start + // address from the builtins table. + UseScratchRegisterScope temps(masm); + Register builtin = temps.Acquire(); + __ Pop(builtin); __ AddP(sp, sp, Operand(BuiltinContinuationFrameConstants::kFixedFrameSizeFromFp)); __ Pop(r0); __ LoadRR(r14, r0); - __ AddP(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); - __ Jump(ip); + __ LoadEntryFromBuiltinIndex(builtin); + __ Jump(builtin); } } // namespace @@ -1745,13 +1762,14 @@ void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { // r2: actual number of arguments // r3: callable { + Register scratch = r5; Label loop; // Calculate the copy start address (destination). Copy end address is sp. __ AddP(r4, sp, r4); __ bind(&loop); - __ LoadP(ip, MemOperand(r4, -kPointerSize)); - __ StoreP(ip, MemOperand(r4)); + __ LoadP(scratch, MemOperand(r4, -kPointerSize)); + __ StoreP(scratch, MemOperand(r4)); __ SubP(r4, Operand(kPointerSize)); __ CmpP(r4, sp); __ bne(&loop); @@ -1944,7 +1962,7 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, // Check for stack overflow. Label stack_overflow; - Generate_StackOverflowCheck(masm, r6, ip, &stack_overflow); + Generate_StackOverflowCheck(masm, r6, scratch, &stack_overflow); // Push arguments onto the stack (thisArgument is already on the stack). { @@ -1955,13 +1973,13 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); __ LoadRR(r1, r6); __ bind(&loop); - __ LoadP(ip, MemOperand(r4, kPointerSize)); + __ LoadP(scratch, MemOperand(r4, kPointerSize)); __ la(r4, MemOperand(r4, kPointerSize)); - __ CompareRoot(ip, RootIndex::kTheHoleValue); + __ CompareRoot(scratch, RootIndex::kTheHoleValue); __ bne(&skip, Label::kNear); - __ LoadRoot(ip, RootIndex::kUndefinedValue); + __ LoadRoot(scratch, RootIndex::kUndefinedValue); __ bind(&skip); - __ push(ip); + __ push(scratch); __ BranchOnCount(r1, &loop); __ bind(&no_args); __ AddP(r2, r2, r6); @@ -2007,8 +2025,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, // Check if we have an arguments adaptor frame below the function frame. Label arguments_adaptor, arguments_done; __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ LoadP(ip, MemOperand(r6, CommonFrameConstants::kContextOrFrameTypeOffset)); - __ CmpP(ip, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); + __ LoadP(scratch, + MemOperand(r6, CommonFrameConstants::kContextOrFrameTypeOffset)); + __ CmpP(scratch, + Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); __ beq(&arguments_adaptor); { __ LoadP(r7, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); @@ -2042,9 +2062,9 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, __ AddP(r2, r2, r7); __ bind(&loop); { - __ ShiftLeftP(ip, r7, Operand(kPointerSizeLog2)); - __ LoadP(ip, MemOperand(r6, ip)); - __ push(ip); + __ ShiftLeftP(scratch, r7, Operand(kPointerSizeLog2)); + __ LoadP(scratch, MemOperand(r6, scratch)); + __ push(scratch); __ SubP(r7, r7, Operand(1)); __ CmpP(r7, Operand::Zero()); __ bne(&loop); @@ -2189,10 +2209,11 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { // -- r6 : the number of [[BoundArguments]] // ----------------------------------- + Register scratch = r8; // Reserve stack space for the [[BoundArguments]]. { Label done; - __ LoadRR(r8, sp); // preserve previous stack pointer + __ LoadRR(scratch, sp); // preserve previous stack pointer __ ShiftLeftP(r9, r6, Operand(kPointerSizeLog2)); __ SubP(sp, sp, r9); // Check the stack for overflow. We are not trying to catch interruptions @@ -2201,7 +2222,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { __ CompareRoot(sp, RootIndex::kRealStackLimit); __ bgt(&done); // Signed comparison. // Restore the stack pointer. - __ LoadRR(sp, r8); + __ LoadRR(sp, scratch); { FrameScope scope(masm, StackFrame::MANUAL); __ EnterFrame(StackFrame::INTERNAL); @@ -2221,7 +2242,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { __ beq(&skip); __ LoadRR(r1, r2); __ bind(&loop); - __ LoadP(r0, MemOperand(r8, r7)); + __ LoadP(r0, MemOperand(scratch, r7)); __ StoreP(r0, MemOperand(sp, r7)); __ AddP(r7, r7, Operand(kPointerSize)); __ BranchOnCount(r1, &loop); @@ -2257,9 +2278,9 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) { __ AssertBoundFunction(r3); // Patch the receiver to [[BoundThis]]. - __ LoadP(ip, FieldMemOperand(r3, JSBoundFunction::kBoundThisOffset)); + __ LoadP(r5, FieldMemOperand(r3, JSBoundFunction::kBoundThisOffset)); __ ShiftLeftP(r1, r2, Operand(kPointerSizeLog2)); - __ StoreP(ip, MemOperand(sp, r1)); + __ StoreP(r5, MemOperand(sp, r1)); // Push the [[BoundArguments]] onto the stack. Generate_PushBoundArguments(masm); @@ -2749,7 +2770,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, __ CompareRoot(r1, RootIndex::kTheHoleValue); // Cannot use check here as it attempts to generate call into runtime. __ beq(&okay, Label::kNear); - __ stop("Unexpected pending exception"); + __ stop(); __ bind(&okay); } @@ -3000,13 +3021,22 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm, __ LoadlB(scratch, MemOperand(scratch, 0)); __ CmpP(scratch, Operand::Zero()); - Label profiler_disabled; - Label end_profiler_check; - __ beq(&profiler_disabled, Label::kNear); - __ Move(scratch, thunk_ref); - __ b(&end_profiler_check, Label::kNear); - __ bind(&profiler_disabled); - __ LoadRR(scratch, function_address); + Label profiler_enabled, end_profiler_check; + __ bne(&profiler_enabled, Label::kNear); + __ Move(scratch, ExternalReference::address_of_runtime_stats_flag()); + __ LoadlW(scratch, MemOperand(scratch, 0)); + __ CmpP(scratch, Operand::Zero()); + __ bne(&profiler_enabled, Label::kNear); + { + // Call the api function directly. + __ LoadRR(scratch, function_address); + __ b(&end_profiler_check, Label::kNear); + } + __ bind(&profiler_enabled); + { + // Additional parameter is the address of the actual callback. + __ Move(scratch, thunk_ref); + } __ bind(&end_profiler_check); // Allocate HandleScope in callee-save registers. @@ -3304,7 +3334,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) { void Builtins::Generate_DirectCEntry(MacroAssembler* masm) { // Unused. - __ stop(0); + __ stop(); } #undef __ diff --git a/deps/v8/src/builtins/setup-builtins-internal.cc b/deps/v8/src/builtins/setup-builtins-internal.cc index e3403c601d..7188eb04a8 100644 --- a/deps/v8/src/builtins/setup-builtins-internal.cc +++ b/deps/v8/src/builtins/setup-builtins-internal.cc @@ -157,10 +157,7 @@ Code BuildWithCodeStubAssemblerJS(Isolate* isolate, int32_t builtin_index, // to code targets without dereferencing their handles. CanonicalHandleScope canonical(isolate); - SegmentSize segment_size = isolate->serializer_enabled() - ? SegmentSize::kLarge - : SegmentSize::kDefault; - Zone zone(isolate->allocator(), ZONE_NAME, segment_size); + Zone zone(isolate->allocator(), ZONE_NAME); const int argc_with_recv = (argc == SharedFunctionInfo::kDontAdaptArgumentsSentinel) ? 0 : argc + 1; compiler::CodeAssemblerState state( @@ -181,10 +178,7 @@ Code BuildWithCodeStubAssemblerCS(Isolate* isolate, int32_t builtin_index, // Canonicalize handles, so that we can share constant pool entries pointing // to code targets without dereferencing their handles. CanonicalHandleScope canonical(isolate); - SegmentSize segment_size = isolate->serializer_enabled() - ? SegmentSize::kLarge - : SegmentSize::kDefault; - Zone zone(isolate->allocator(), ZONE_NAME, segment_size); + Zone zone(isolate->allocator(), ZONE_NAME); // The interface descriptor with given key must be initialized at this point // and this construction just queries the details from the descriptors table. CallInterfaceDescriptor descriptor(interface_descriptor); @@ -232,9 +226,9 @@ void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) { RelocInfo::ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT) | RelocInfo::ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT) | RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET); - HeapIterator iterator(isolate->heap()); - for (HeapObject obj = iterator.next(); !obj.is_null(); - obj = iterator.next()) { + HeapObjectIterator iterator(isolate->heap()); + for (HeapObject obj = iterator.Next(); !obj.is_null(); + obj = iterator.Next()) { if (!obj.IsCode()) continue; Code code = Code::cast(obj); bool flush_icache = false; @@ -282,10 +276,6 @@ Code GenerateBytecodeHandler(Isolate* isolate, int builtin_index, } // namespace -#ifdef _MSC_VER -#pragma optimize( "", off ) -#endif - // static void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) { Builtins* builtins = isolate->builtins(); @@ -363,10 +353,5 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) { builtins->MarkInitialized(); } -#ifdef _MSC_VER -#pragma optimize( "", on ) -#endif - - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/string-endswith.tq b/deps/v8/src/builtins/string-endswith.tq index 16405d4c12..8b9fe84dfb 100644 --- a/deps/v8/src/builtins/string-endswith.tq +++ b/deps/v8/src/builtins/string-endswith.tq @@ -28,12 +28,13 @@ namespace string { // https://tc39.github.io/ecma262/#sec-string.prototype.endswith transitioning javascript builtin StringPrototypeEndsWith( - context: Context, receiver: Object, ...arguments): Boolean { + js-implicit context: Context, receiver: Object)(...arguments): Boolean { const searchString: Object = arguments[0]; const endPosition: Object = arguments[1]; + const kBuiltinName: constexpr string = 'String.prototype.endsWith'; // 1. Let O be ? RequireObjectCoercible(this value). - const object: Object = RequireObjectCoercible(receiver); + const object: Object = RequireObjectCoercible(receiver, kBuiltinName); // 2. Let S be ? ToString(O). const string: String = ToString_Inline(context, object); @@ -41,7 +42,7 @@ namespace string { // 3. Let isRegExp be ? IsRegExp(searchString). // 4. If isRegExp is true, throw a TypeError exception. if (IsRegExp(searchString)) { - ThrowTypeError(kFirstArgumentNotRegExp, 'String.prototype.endsWith'); + ThrowTypeError(kFirstArgumentNotRegExp, kBuiltinName); } // 5. Let searchStr be ? ToString(searchString). @@ -63,7 +64,7 @@ namespace string { const searchLength: Smi = searchStr.length_smi; // 10. Let start be end - searchLength. - let start = end - searchLength; + const start = end - searchLength; // 11. If start is less than 0, return false. if (start < 0) return False; diff --git a/deps/v8/src/builtins/string-html.tq b/deps/v8/src/builtins/string-html.tq index a2b1625206..80b5f77887 100644 --- a/deps/v8/src/builtins/string-html.tq +++ b/deps/v8/src/builtins/string-html.tq @@ -22,22 +22,23 @@ namespace string_html { // https://tc39.github.io/ecma262/#sec-string.prototype.anchor transitioning javascript builtin StringPrototypeAnchor( - context: Context, receiver: Object, ...arguments): String { + js-implicit context: Context, receiver: Object)(...arguments): String { return CreateHTML( receiver, 'String.prototype.anchor', 'a', 'name', arguments[0]); } // https://tc39.github.io/ecma262/#sec-string.prototype.big transitioning javascript builtin - StringPrototypeBig(context: Context, receiver: Object, ...arguments): String { + StringPrototypeBig(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.big', 'big', kEmptyString, kEmptyString); } // https://tc39.github.io/ecma262/#sec-string.prototype.blink transitioning javascript builtin - StringPrototypeBlink(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeBlink(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.blink', 'blink', kEmptyString, kEmptyString); @@ -45,56 +46,56 @@ namespace string_html { // https://tc39.github.io/ecma262/#sec-string.prototype.bold transitioning javascript builtin - StringPrototypeBold(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeBold(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.bold', 'b', kEmptyString, kEmptyString); } // https://tc39.github.io/ecma262/#sec-string.prototype.fontcolor transitioning javascript builtin - StringPrototypeFontcolor(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeFontcolor(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.fontcolor', 'font', 'color', arguments[0]); } // https://tc39.github.io/ecma262/#sec-string.prototype.fontsize transitioning javascript builtin - StringPrototypeFontsize(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeFontsize(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.fontsize', 'font', 'size', arguments[0]); } // https://tc39.github.io/ecma262/#sec-string.prototype.fixed transitioning javascript builtin - StringPrototypeFixed(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeFixed(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.fixed', 'tt', kEmptyString, kEmptyString); } // https://tc39.github.io/ecma262/#sec-string.prototype.italics transitioning javascript builtin - StringPrototypeItalics(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeItalics(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.italics', 'i', kEmptyString, kEmptyString); } // https://tc39.github.io/ecma262/#sec-string.prototype.link transitioning javascript builtin - StringPrototypeLink(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeLink(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.link', 'a', 'href', arguments[0]); } // https://tc39.github.io/ecma262/#sec-string.prototype.small transitioning javascript builtin - StringPrototypeSmall(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeSmall(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.small', 'small', kEmptyString, kEmptyString); @@ -102,8 +103,8 @@ namespace string_html { // https://tc39.github.io/ecma262/#sec-string.prototype.strike transitioning javascript builtin - StringPrototypeStrike(context: Context, receiver: Object, ...arguments): - String { + StringPrototypeStrike(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.strike', 'strike', kEmptyString, kEmptyString); @@ -111,14 +112,16 @@ namespace string_html { // https://tc39.github.io/ecma262/#sec-string.prototype.sub transitioning javascript builtin - StringPrototypeSub(context: Context, receiver: Object, ...arguments): String { + StringPrototypeSub(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.sub', 'sub', kEmptyString, kEmptyString); } // https://tc39.github.io/ecma262/#sec-string.prototype.sup transitioning javascript builtin - StringPrototypeSup(context: Context, receiver: Object, ...arguments): String { + StringPrototypeSup(js-implicit context: Context, receiver: Object)( + ...arguments): String { return CreateHTML( receiver, 'String.prototype.sup', 'sup', kEmptyString, kEmptyString); } diff --git a/deps/v8/src/builtins/string-iterator.tq b/deps/v8/src/builtins/string-iterator.tq index f5c6099c25..5b8f864661 100644 --- a/deps/v8/src/builtins/string-iterator.tq +++ b/deps/v8/src/builtins/string-iterator.tq @@ -17,7 +17,7 @@ namespace string_iterator { // ES6 #sec-string.prototype-@@iterator transitioning javascript builtin StringPrototypeIterator( - implicit context: Context)(receiver: Object): JSStringIterator { + js-implicit context: Context)(receiver: Object): JSStringIterator { const name: String = ToThisString(receiver, 'String.prototype[Symbol.iterator]'); const index: Smi = 0; @@ -26,7 +26,7 @@ namespace string_iterator { // ES6 #sec-%stringiteratorprototype%.next transitioning javascript builtin StringIteratorPrototypeNext( - implicit context: Context)(receiver: Object): JSIteratorResult { + js-implicit context: Context)(receiver: Object): JSObject { const iterator = Cast<JSStringIterator>(receiver) otherwise ThrowTypeError( kIncompatibleMethodReceiver, 'String Iterator.prototype.next', receiver); @@ -34,13 +34,13 @@ namespace string_iterator { const position: intptr = SmiUntag(iterator.next_index); const length: intptr = string.length_intptr; if (position >= length) { - return NewJSIteratorResult(Undefined, True); + return AllocateJSIteratorResult(Undefined, True); } // Move to next codepoint. const encoding = UTF16; const ch = string::LoadSurrogatePairAt(string, length, position, encoding); - const value: String = string::StringFromSingleCodePoint(ch, encoding); + const value: String = string::StringFromSingleUTF16EncodedCodePoint(ch); iterator.next_index = SmiTag(position + value.length_intptr); - return NewJSIteratorResult(value, False); + return AllocateJSIteratorResult(value, False); } } diff --git a/deps/v8/src/builtins/string-repeat.tq b/deps/v8/src/builtins/string-repeat.tq index f2590011ea..0d9d4ee498 100644 --- a/deps/v8/src/builtins/string-repeat.tq +++ b/deps/v8/src/builtins/string-repeat.tq @@ -28,7 +28,7 @@ namespace string_repeat { // https://tc39.github.io/ecma262/#sec-string.prototype.repeat transitioning javascript builtin StringPrototypeRepeat( - context: Context, receiver: Object, count: Object): String { + js-implicit context: Context, receiver: Object)(count: Object): String { // 1. Let O be ? RequireObjectCoercible(this value). // 2. Let S be ? ToString(O). const s: String = ToThisString(receiver, kBuiltinName); diff --git a/deps/v8/src/builtins/string-slice.tq b/deps/v8/src/builtins/string-slice.tq index 41eb38b0ad..b066fb7669 100644 --- a/deps/v8/src/builtins/string-slice.tq +++ b/deps/v8/src/builtins/string-slice.tq @@ -9,7 +9,7 @@ namespace string_slice { // ES6 #sec-string.prototype.slice ( start, end ) // https://tc39.github.io/ecma262/#sec-string.prototype.slice transitioning javascript builtin StringPrototypeSlice( - implicit context: Context)(receiver: Object, ...arguments): String { + js-implicit context: Context, receiver: Object)(...arguments): String { // 1. Let O be ? RequireObjectCoercible(this value). // 2. Let S be ? ToString(O). const string: String = ToThisString(receiver, 'String.prototype.slice'); diff --git a/deps/v8/src/builtins/string-startswith.tq b/deps/v8/src/builtins/string-startswith.tq index 1f885a2afd..b03e67ecf5 100644 --- a/deps/v8/src/builtins/string-startswith.tq +++ b/deps/v8/src/builtins/string-startswith.tq @@ -8,23 +8,15 @@ namespace string { extern macro RegExpBuiltinsAssembler::IsRegExp(implicit context: Context)(Object): bool; - // TODO(ryzokuken): Add RequireObjectCoercible to base.tq and update callsites - macro RequireObjectCoercible(implicit context: Context)(argument: Object): - Object { - if (IsNullOrUndefined(argument)) { - ThrowTypeError(kCalledOnNullOrUndefined, 'String.prototype.startsWith'); - } - return argument; - } - // https://tc39.github.io/ecma262/#sec-string.prototype.startswith transitioning javascript builtin StringPrototypeStartsWith( - context: Context, receiver: Object, ...arguments): Boolean { + js-implicit context: Context, receiver: Object)(...arguments): Boolean { const searchString: Object = arguments[0]; const position: Object = arguments[1]; + const kBuiltinName: constexpr string = 'String.prototype.startsWith'; // 1. Let O be ? RequireObjectCoercible(this value). - const object: Object = RequireObjectCoercible(receiver); + const object: Object = RequireObjectCoercible(receiver, kBuiltinName); // 2. Let S be ? ToString(O). const string: String = ToString_Inline(context, object); @@ -32,7 +24,7 @@ namespace string { // 3. Let isRegExp be ? IsRegExp(searchString). // 4. If isRegExp is true, throw a TypeError exception. if (IsRegExp(searchString)) { - ThrowTypeError(kFirstArgumentNotRegExp, 'String.prototype.startsWith'); + ThrowTypeError(kFirstArgumentNotRegExp, kBuiltinName); } // 5. Let searchStr be ? ToString(searchString). diff --git a/deps/v8/src/builtins/string-substring.tq b/deps/v8/src/builtins/string-substring.tq index f322eeed06..1fafb8af43 100644 --- a/deps/v8/src/builtins/string-substring.tq +++ b/deps/v8/src/builtins/string-substring.tq @@ -28,7 +28,7 @@ namespace string_substring { // ES6 #sec-string.prototype.substring transitioning javascript builtin StringPrototypeSubstring( - implicit context: Context)(receiver: Object, ...arguments): String { + js-implicit context: Context, receiver: Object)(...arguments): String { // Check that {receiver} is coercible to Object and convert it to a String. const string: String = ToThisString(receiver, 'String.prototype.substring'); const length = string.length_smi; diff --git a/deps/v8/src/builtins/string.tq b/deps/v8/src/builtins/string.tq index 1e5a74eb49..dbcc5799e1 100644 --- a/deps/v8/src/builtins/string.tq +++ b/deps/v8/src/builtins/string.tq @@ -7,20 +7,21 @@ namespace string { // ES6 #sec-string.prototype.tostring transitioning javascript builtin - StringPrototypeToString(implicit context: Context)(receiver: Object): Object { + StringPrototypeToString(js-implicit context: Context)(receiver: Object): + Object { return ToThisValue(receiver, kString, 'String.prototype.toString'); } // ES6 #sec-string.prototype.valueof transitioning javascript builtin - StringPrototypeValueOf(implicit context: Context)(receiver: Object): Object { + StringPrototypeValueOf(js-implicit context: Context)(receiver: Object): + Object { return ToThisValue(receiver, kString, 'String.prototype.valueOf'); } extern macro StringBuiltinsAssembler::LoadSurrogatePairAt( String, intptr, intptr, constexpr UnicodeEncoding): int32; - extern macro StringFromSingleCodePoint(int32, constexpr UnicodeEncoding): - String; + extern macro StringFromSingleUTF16EncodedCodePoint(int32): String; // This function assumes StringPrimitiveWithNoCustomIteration is true. transitioning builtin StringToList(implicit context: Context)(string: String): @@ -38,7 +39,7 @@ namespace string { let i: intptr = 0; while (i < stringLength) { const ch: int32 = LoadSurrogatePairAt(string, stringLength, i, encoding); - const value: String = StringFromSingleCodePoint(ch, encoding); + const value: String = StringFromSingleUTF16EncodedCodePoint(ch); elements[arrayLength] = value; // Increment and continue the loop. i = i + value.length_intptr; @@ -52,9 +53,9 @@ namespace string { } transitioning macro GenerateStringAt(implicit context: Context)( - receiver: Object, position: Object, methodName: constexpr string): - never labels IfInBounds(String, intptr, intptr), - IfOutOfBounds { + receiver: Object, position: Object, + methodName: constexpr string): never labels + IfInBounds(String, intptr, intptr), IfOutOfBounds { // Check that {receiver} is coercible to Object and convert it to a String. const string: String = ToThisString(receiver, methodName); // Convert the {position} to a Smi and check that it's in bounds of @@ -70,12 +71,13 @@ namespace string { // ES6 #sec-string.prototype.charat transitioning javascript builtin StringPrototypeCharAt( - implicit context: Context)(receiver: Object, position: Object): Object { + js-implicit context: Context, + receiver: Object)(position: Object): Object { try { GenerateStringAt(receiver, position, 'String.prototype.charAt') otherwise IfInBounds, IfOutOfBounds; } - label IfInBounds(string: String, index: intptr, length: intptr) { + label IfInBounds(string: String, index: intptr, _length: intptr) { const code: int32 = StringCharCodeAt(string, index); return StringFromSingleCharCode(code); } @@ -86,12 +88,13 @@ namespace string { // ES6 #sec-string.prototype.charcodeat transitioning javascript builtin StringPrototypeCharCodeAt( - implicit context: Context)(receiver: Object, position: Object): Object { + js-implicit context: Context, + receiver: Object)(position: Object): Object { try { GenerateStringAt(receiver, position, 'String.prototype.charCodeAt') otherwise IfInBounds, IfOutOfBounds; } - label IfInBounds(string: String, index: intptr, length: intptr) { + label IfInBounds(string: String, index: intptr, _length: intptr) { const code: int32 = StringCharCodeAt(string, index); return Convert<Smi>(code); } @@ -102,7 +105,8 @@ namespace string { // ES6 #sec-string.prototype.codepointat transitioning javascript builtin StringPrototypeCodePointAt( - implicit context: Context)(receiver: Object, position: Object): Object { + js-implicit context: Context, + receiver: Object)(position: Object): Object { try { GenerateStringAt(receiver, position, 'String.prototype.codePointAt') otherwise IfInBounds, IfOutOfBounds; @@ -121,7 +125,7 @@ namespace string { // ES6 String.prototype.concat(...args) // ES6 #sec-string.prototype.concat transitioning javascript builtin StringPrototypeConcat( - implicit context: Context)(receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { // Check that {receiver} is coercible to Object and convert it to a String. let string: String = ToThisString(receiver, 'String.prototype.concat'); diff --git a/deps/v8/src/builtins/typed-array-createtypedarray.tq b/deps/v8/src/builtins/typed-array-createtypedarray.tq index a0d745b2f4..f6ab289e12 100644 --- a/deps/v8/src/builtins/typed-array-createtypedarray.tq +++ b/deps/v8/src/builtins/typed-array-createtypedarray.tq @@ -8,30 +8,77 @@ namespace typed_array_createtypedarray { extern builtin IterableToListMayPreserveHoles(Context, Object, Callable): JSArray; - extern macro ConstructorBuiltinsAssembler::EmitFastNewObject( - implicit context: Context)(JSFunction, JSReceiver): JSTypedArray; extern macro TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer( - implicit context: Context)(JSTypedArray, uintptr): JSArrayBuffer; + implicit context: Context)(uintptr): JSArrayBuffer; + extern macro CodeStubAssembler::AllocateByteArray(uintptr): ByteArray; extern macro TypedArrayBuiltinsAssembler::GetDefaultConstructor( implicit context: Context)(JSTypedArray): JSFunction; extern macro TypedArrayBuiltinsAssembler::IsSharedArrayBuffer(JSArrayBuffer): bool; - extern macro TypedArrayBuiltinsAssembler::SetupTypedArray( - JSTypedArray, uintptr, uintptr, uintptr): void; + extern macro TypedArrayBuiltinsAssembler::SetupTypedArrayEmbedderFields( + JSTypedArray): void; extern runtime ThrowInvalidTypedArrayAlignment(implicit context: Context)( Map, String): never; extern runtime TypedArrayCopyElements(Context, JSTypedArray, Object, Number): void; + transitioning macro AllocateTypedArray(implicit context: Context)( + isOnHeap: constexpr bool, map: Map, buffer: JSArrayBuffer, + byteOffset: uintptr, byteLength: uintptr, length: uintptr): JSTypedArray { + let elements: ByteArray; + let externalPointer: RawPtr; + let basePointer: ByteArray | Smi; + if constexpr (isOnHeap) { + elements = AllocateByteArray(byteLength); + basePointer = elements; + externalPointer = PointerConstant(kExternalPointerForOnHeapArray); + } else { + basePointer = Convert<Smi>(0); + + // The max byteOffset is 8 * MaxSmi on the particular platform. 32 bit + // platforms are self-limiting, because we can't allocate an array bigger + // than our 32-bit arithmetic range anyway. 64 bit platforms could + // theoretically have an offset up to 2^35 - 1. + const backingStore: RawPtr = buffer.backing_store; + externalPointer = backingStore + Convert<intptr>(byteOffset); + + // Assert no overflow has occurred. Only assert if the mock array buffer + // allocator is NOT used. When the mock array buffer is used, impossibly + // large allocations are allowed that would erroneously cause an overflow + // and this assertion to fail. + assert( + IsMockArrayBufferAllocatorFlag() || + Convert<uintptr>(externalPointer) >= Convert<uintptr>(backingStore)); + + elements = kEmptyByteArray; + } + + // We can't just build the new object with "new JSTypedArray" here because + // Torque doesn't know its full size including embedder fields, so use CSA + // for the allocation step. + const typedArray = + UnsafeCast<JSTypedArray>(AllocateFastOrSlowJSObjectFromMap(map)); + typedArray.elements = elements; + typedArray.buffer = buffer; + typedArray.byte_offset = byteOffset; + typedArray.byte_length = byteLength; + typedArray.length = length; + typedArray.external_pointer = externalPointer; + typedArray.base_pointer = basePointer; + SetupTypedArrayEmbedderFields(typedArray); + return typedArray; + } + transitioning macro TypedArrayInitialize(implicit context: Context)( - initialize: constexpr bool, typedArray: JSTypedArray, length: PositiveSmi, + initialize: constexpr bool, map: Map, length: PositiveSmi, elementsInfo: typed_array::TypedArrayElementsInfo, - bufferConstructor: JSReceiver): uintptr { + bufferConstructor: JSReceiver): JSTypedArray { const byteLength = elementsInfo.CalculateByteLength(length) otherwise ThrowRangeError(kInvalidArrayBufferLength); const byteLengthNum = Convert<Number>(byteLength); const defaultConstructor = GetArrayBufferFunction(); + const byteOffset: uintptr = 0; try { if (bufferConstructor != defaultConstructor) { @@ -39,14 +86,21 @@ namespace typed_array_createtypedarray { defaultConstructor, bufferConstructor, byteLengthNum)); } - if (byteLength > V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP) goto AllocateOffHeap; + if (byteLength > kMaxTypedArrayInHeap) goto AllocateOffHeap; + + const buffer = AllocateEmptyOnHeapBuffer(byteLength); - AllocateEmptyOnHeapBuffer(typedArray, byteLength); + const isOnHeap: constexpr bool = true; + const typedArray = AllocateTypedArray( + isOnHeap, map, buffer, byteOffset, byteLength, + Convert<uintptr>(length)); if constexpr (initialize) { const backingStore = typedArray.data_ptr; typed_array::CallCMemset(backingStore, 0, byteLength); } + + return typedArray; } label AllocateOffHeap { if constexpr (initialize) { @@ -58,22 +112,18 @@ namespace typed_array_createtypedarray { } label AttachOffHeapBuffer(bufferObj: Object) { const buffer = Cast<JSArrayBuffer>(bufferObj) otherwise unreachable; - const byteOffset: uintptr = 0; - typedArray.AttachOffHeapBuffer(buffer, byteOffset); + const isOnHeap: constexpr bool = false; + return AllocateTypedArray( + isOnHeap, map, buffer, byteOffset, byteLength, + Convert<uintptr>(length)); } - - const byteOffset: uintptr = 0; - SetupTypedArray( - typedArray, Convert<uintptr>(length), byteOffset, byteLength); - - return byteLength; } // 22.2.4.2 TypedArray ( length ) // ES #sec-typedarray-length transitioning macro ConstructByLength(implicit context: Context)( - typedArray: JSTypedArray, length: Object, - elementsInfo: typed_array::TypedArrayElementsInfo): void { + map: Map, length: Object, + elementsInfo: typed_array::TypedArrayElementsInfo): JSTypedArray { const convertedLength: Number = ToInteger_Inline(context, length, kTruncateMinusZero); // The maximum length of a TypedArray is MaxSmi(). @@ -84,23 +134,22 @@ namespace typed_array_createtypedarray { otherwise ThrowRangeError(kInvalidTypedArrayLength, length); const defaultConstructor: Constructor = GetArrayBufferFunction(); const initialize: constexpr bool = true; - TypedArrayInitialize( - initialize, typedArray, positiveLength, elementsInfo, - defaultConstructor); + return TypedArrayInitialize( + initialize, map, positiveLength, elementsInfo, defaultConstructor); } // 22.2.4.4 TypedArray ( object ) // ES #sec-typedarray-object transitioning macro ConstructByArrayLike(implicit context: Context)( - typedArray: JSTypedArray, arrayLike: HeapObject, initialLength: Object, + map: Map, arrayLike: HeapObject, initialLength: Object, elementsInfo: typed_array::TypedArrayElementsInfo, - bufferConstructor: JSReceiver): void { + bufferConstructor: JSReceiver): JSTypedArray { // The caller has looked up length on arrayLike, which is observable. const length: PositiveSmi = ToSmiLength(initialLength) otherwise ThrowRangeError(kInvalidTypedArrayLength, initialLength); const initialize: constexpr bool = false; - const byteLength = TypedArrayInitialize( - initialize, typedArray, length, elementsInfo, bufferConstructor); + const typedArray = TypedArrayInitialize( + initialize, map, length, elementsInfo, bufferConstructor); try { const src: JSTypedArray = Cast<JSTypedArray>(arrayLike) otherwise IfSlow; @@ -112,6 +161,7 @@ namespace typed_array_createtypedarray { goto IfSlow; } else if (length > 0) { + const byteLength = typedArray.byte_length; assert(byteLength <= kArrayBufferMaxByteLength); typed_array::CallCMemcpy(typedArray.data_ptr, src.data_ptr, byteLength); } @@ -121,13 +171,13 @@ namespace typed_array_createtypedarray { TypedArrayCopyElements(context, typedArray, arrayLike, length); } } + return typedArray; } // 22.2.4.4 TypedArray ( object ) // ES #sec-typedarray-object transitioning macro ConstructByIterable(implicit context: Context)( - typedArray: JSTypedArray, iterable: JSReceiver, iteratorFn: Callable, - elementsInfo: typed_array::TypedArrayElementsInfo): never + iterable: JSReceiver, iteratorFn: Callable): never labels IfConstructByArrayLike(HeapObject, Object, JSReceiver) { const array: JSArray = IterableToListMayPreserveHoles(context, iterable, iteratorFn); @@ -137,8 +187,7 @@ namespace typed_array_createtypedarray { // 22.2.4.3 TypedArray ( typedArray ) // ES #sec-typedarray-typedarray transitioning macro ConstructByTypedArray(implicit context: Context)( - typedArray: JSTypedArray, srcTypedArray: JSTypedArray, - elementsInfo: typed_array::TypedArrayElementsInfo): never + srcTypedArray: JSTypedArray): never labels IfConstructByArrayLike(HeapObject, Object, JSReceiver) { let bufferConstructor: JSReceiver = GetArrayBufferFunction(); const srcBuffer: JSArrayBuffer = srcTypedArray.buffer; @@ -161,8 +210,8 @@ namespace typed_array_createtypedarray { // 22.2.4.5 TypedArray ( buffer, byteOffset, length ) // ES #sec-typedarray-buffer-byteoffset-length transitioning macro ConstructByArrayBuffer(implicit context: Context)( - typedArray: JSTypedArray, buffer: JSArrayBuffer, byteOffset: Object, - length: Object, elementsInfo: typed_array::TypedArrayElementsInfo): void { + map: Map, buffer: JSArrayBuffer, byteOffset: Object, length: Object, + elementsInfo: typed_array::TypedArrayElementsInfo): JSTypedArray { try { let offset: uintptr = 0; if (byteOffset != Undefined) { @@ -224,12 +273,13 @@ namespace typed_array_createtypedarray { goto IfInvalidLength; } - SetupTypedArray( - typedArray, Convert<uintptr>(newLength), offset, newByteLength); - typedArray.AttachOffHeapBuffer(buffer, offset); + const isOnHeap: constexpr bool = false; + return AllocateTypedArray( + isOnHeap, map, buffer, offset, newByteLength, + Convert<uintptr>(newLength)); } label IfInvalidAlignment(problemString: String) deferred { - ThrowInvalidTypedArrayAlignment(typedArray.map, problemString); + ThrowInvalidTypedArrayAlignment(map, problemString); } label IfInvalidByteLength deferred { ThrowRangeError(kInvalidArrayBufferLength); @@ -242,16 +292,15 @@ namespace typed_array_createtypedarray { } } - transitioning macro ConstructByJSReceiver(implicit context: Context)( - array: JSTypedArray, obj: JSReceiver, - elementsInfo: typed_array::TypedArrayElementsInfo): never + transitioning macro ConstructByJSReceiver(implicit context: + Context)(obj: JSReceiver): never labels IfConstructByArrayLike(HeapObject, Object, JSReceiver) { try { const iteratorMethod: Object = GetIteratorMethod(obj) otherwise IfIteratorUndefined; const iteratorFn: Callable = Cast<Callable>(iteratorMethod) otherwise ThrowTypeError(kIteratorSymbolNonCallable); - ConstructByIterable(array, obj, iteratorFn, elementsInfo) + ConstructByIterable(obj, iteratorFn) otherwise IfConstructByArrayLike; } label IfIteratorUndefined { @@ -273,22 +322,12 @@ namespace typed_array_createtypedarray { assert(IsConstructor(target)); // 4. Let O be ? AllocateTypedArray(constructorName, NewTarget, // "%TypedArrayPrototype%"). - const array: JSTypedArray = EmitFastNewObject(target, newTarget); - // We need to set the byte_offset / byte_length to some sane values - // to keep the heap verifier happy. - // TODO(bmeurer, v8:4153): Fix this initialization to not use - // EmitFastNewObject, which causes the problem, since it puts - // Undefined into all slots of the object even though that - // doesn't make any sense for these fields. - array.byte_offset = 0; - array.byte_length = 0; - array.length = 0; - array.base_pointer = Convert<Smi>(0); + const map = GetDerivedMap(target, newTarget); // 5. Let elementSize be the Number value of the Element Size value in Table // 56 for constructorName. const elementsInfo: typed_array::TypedArrayElementsInfo = - typed_array::GetTypedArrayElementsInfo(array); + typed_array::GetTypedArrayElementsInfo(map); try { typeswitch (arg1) { @@ -296,15 +335,13 @@ namespace typed_array_createtypedarray { goto IfConstructByLength(length); } case (buffer: JSArrayBuffer): { - ConstructByArrayBuffer(array, buffer, arg2, arg3, elementsInfo); + return ConstructByArrayBuffer(map, buffer, arg2, arg3, elementsInfo); } case (typedArray: JSTypedArray): { - ConstructByTypedArray(array, typedArray, elementsInfo) - otherwise IfConstructByArrayLike; + ConstructByTypedArray(typedArray) otherwise IfConstructByArrayLike; } case (obj: JSReceiver): { - ConstructByJSReceiver(array, obj, elementsInfo) - otherwise IfConstructByArrayLike; + ConstructByJSReceiver(obj) otherwise IfConstructByArrayLike; } // The first argument was a number or fell through and is treated as // a number. https://tc39.github.io/ecma262/#sec-typedarray-length @@ -314,14 +351,13 @@ namespace typed_array_createtypedarray { } } label IfConstructByLength(length: Object) { - ConstructByLength(array, length, elementsInfo); + return ConstructByLength(map, length, elementsInfo); } label IfConstructByArrayLike( arrayLike: HeapObject, length: Object, bufferConstructor: JSReceiver) { - ConstructByArrayLike( - array, arrayLike, length, elementsInfo, bufferConstructor); + return ConstructByArrayLike( + map, arrayLike, length, elementsInfo, bufferConstructor); } - return array; } transitioning macro TypedArraySpeciesCreate(implicit context: Context)( diff --git a/deps/v8/src/builtins/typed-array-every.tq b/deps/v8/src/builtins/typed-array-every.tq index 4f8804880e..221814cb79 100644 --- a/deps/v8/src/builtins/typed-array-every.tq +++ b/deps/v8/src/builtins/typed-array-every.tq @@ -29,8 +29,8 @@ namespace typed_array_every { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.every transitioning javascript builtin - TypedArrayPrototypeEvery(implicit context: Context)( - receiver: Object, ...arguments): Object { + TypedArrayPrototypeEvery(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // arguments[0] = callback // arguments[1] = thisArg try { diff --git a/deps/v8/src/builtins/typed-array-filter.tq b/deps/v8/src/builtins/typed-array-filter.tq index 9407c3a7af..3937699c73 100644 --- a/deps/v8/src/builtins/typed-array-filter.tq +++ b/deps/v8/src/builtins/typed-array-filter.tq @@ -10,7 +10,7 @@ namespace typed_array_filter { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.filter transitioning javascript builtin TypedArrayPrototypeFilter( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { // arguments[0] = callback // arguments[1] = thisArg try { diff --git a/deps/v8/src/builtins/typed-array-find.tq b/deps/v8/src/builtins/typed-array-find.tq index 3c331eb3bb..be1943ccf4 100644 --- a/deps/v8/src/builtins/typed-array-find.tq +++ b/deps/v8/src/builtins/typed-array-find.tq @@ -29,8 +29,8 @@ namespace typed_array_find { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.find transitioning javascript builtin - TypedArrayPrototypeFind(implicit context: - Context)(receiver: Object, ...arguments): Object { + TypedArrayPrototypeFind(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // arguments[0] = callback // arguments[1] = thisArg try { diff --git a/deps/v8/src/builtins/typed-array-findindex.tq b/deps/v8/src/builtins/typed-array-findindex.tq index 05f112d0d5..a5ee7897d3 100644 --- a/deps/v8/src/builtins/typed-array-findindex.tq +++ b/deps/v8/src/builtins/typed-array-findindex.tq @@ -29,8 +29,8 @@ namespace typed_array_findindex { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.findIndex transitioning javascript builtin - TypedArrayPrototypeFindIndex(implicit context: Context)( - receiver: Object, ...arguments): Object { + TypedArrayPrototypeFindIndex(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // arguments[0] = callback // arguments[1] = thisArg. try { diff --git a/deps/v8/src/builtins/typed-array-foreach.tq b/deps/v8/src/builtins/typed-array-foreach.tq index dbf1a121da..656a22e07d 100644 --- a/deps/v8/src/builtins/typed-array-foreach.tq +++ b/deps/v8/src/builtins/typed-array-foreach.tq @@ -25,8 +25,8 @@ namespace typed_array_foreach { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.every transitioning javascript builtin - TypedArrayPrototypeForEach(implicit context: Context)( - receiver: Object, ...arguments): Object { + TypedArrayPrototypeForEach(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // arguments[0] = callback // arguments[1] = this_arg. diff --git a/deps/v8/src/builtins/typed-array-reduce.tq b/deps/v8/src/builtins/typed-array-reduce.tq index 7af918a07b..d69dc9a98d 100644 --- a/deps/v8/src/builtins/typed-array-reduce.tq +++ b/deps/v8/src/builtins/typed-array-reduce.tq @@ -19,7 +19,7 @@ namespace typed_array_reduce { // BUG(4895): We should throw on detached buffers rather than simply exit. witness.Recheck() otherwise break; const value: Object = witness.Load(k); - if (accumulator == Hole) { + if (accumulator == TheHole) { accumulator = value; } else { accumulator = Call( @@ -27,7 +27,7 @@ namespace typed_array_reduce { witness.GetStable()); } } - if (accumulator == Hole) { + if (accumulator == TheHole) { ThrowTypeError(kReduceNoInitial, kBuiltinName); } return accumulator; @@ -35,8 +35,8 @@ namespace typed_array_reduce { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduce transitioning javascript builtin - TypedArrayPrototypeReduce(implicit context: Context)( - receiver: Object, ...arguments): Object { + TypedArrayPrototypeReduce(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // arguments[0] = callback // arguments[1] = initialValue. try { @@ -45,7 +45,7 @@ namespace typed_array_reduce { const uarray = typed_array::EnsureAttached(array) otherwise IsDetached; const callbackfn = Cast<Callable>(arguments[0]) otherwise NotCallable; - const initialValue = arguments.length >= 2 ? arguments[1] : Hole; + const initialValue = arguments.length >= 2 ? arguments[1] : TheHole; return ReduceAllElements(uarray, callbackfn, initialValue); } label NotCallable deferred { diff --git a/deps/v8/src/builtins/typed-array-reduceright.tq b/deps/v8/src/builtins/typed-array-reduceright.tq index 59ce7ff55b..99a84401ed 100644 --- a/deps/v8/src/builtins/typed-array-reduceright.tq +++ b/deps/v8/src/builtins/typed-array-reduceright.tq @@ -19,7 +19,7 @@ namespace typed_array_reduceright { // BUG(4895): We should throw on detached buffers rather than simply exit. witness.Recheck() otherwise break; const value: Object = witness.Load(k); - if (accumulator == Hole) { + if (accumulator == TheHole) { accumulator = value; } else { accumulator = Call( @@ -27,7 +27,7 @@ namespace typed_array_reduceright { witness.GetStable()); } } - if (accumulator == Hole) { + if (accumulator == TheHole) { ThrowTypeError(kReduceNoInitial, kBuiltinName); } return accumulator; @@ -35,8 +35,8 @@ namespace typed_array_reduceright { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduceright transitioning javascript builtin - TypedArrayPrototypeReduceRight(implicit context: Context)( - receiver: Object, ...arguments): Object { + TypedArrayPrototypeReduceRight( + js-implicit context: Context, receiver: Object)(...arguments): Object { // arguments[0] = callback // arguments[1] = initialValue. try { @@ -45,7 +45,7 @@ namespace typed_array_reduceright { const uarray = typed_array::EnsureAttached(array) otherwise IsDetached; const callbackfn = Cast<Callable>(arguments[0]) otherwise NotCallable; - const initialValue = arguments.length >= 2 ? arguments[1] : Hole; + const initialValue = arguments.length >= 2 ? arguments[1] : TheHole; return ReduceRightAllElements(uarray, callbackfn, initialValue); } diff --git a/deps/v8/src/builtins/typed-array-slice.tq b/deps/v8/src/builtins/typed-array-slice.tq index f45654b71e..c0087ae1be 100644 --- a/deps/v8/src/builtins/typed-array-slice.tq +++ b/deps/v8/src/builtins/typed-array-slice.tq @@ -53,7 +53,7 @@ namespace typed_array_slice { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.slice transitioning javascript builtin TypedArrayPrototypeSlice( - context: Context, receiver: Object, ...arguments): Object { + js-implicit context: Context, receiver: Object)(...arguments): Object { // arguments[0] = start // arguments[1] = end diff --git a/deps/v8/src/builtins/typed-array-some.tq b/deps/v8/src/builtins/typed-array-some.tq index 991cad6b1b..7056650fba 100644 --- a/deps/v8/src/builtins/typed-array-some.tq +++ b/deps/v8/src/builtins/typed-array-some.tq @@ -29,8 +29,8 @@ namespace typed_array_some { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.some transitioning javascript builtin - TypedArrayPrototypeSome(implicit context: - Context)(receiver: Object, ...arguments): Object { + TypedArrayPrototypeSome(js-implicit context: Context, receiver: Object)( + ...arguments): Object { // arguments[0] = callback // arguments[1] = thisArg. try { diff --git a/deps/v8/src/builtins/typed-array-subarray.tq b/deps/v8/src/builtins/typed-array-subarray.tq index 54b945f44e..4f98123f82 100644 --- a/deps/v8/src/builtins/typed-array-subarray.tq +++ b/deps/v8/src/builtins/typed-array-subarray.tq @@ -5,7 +5,8 @@ namespace typed_array_subarray { // ES %TypedArray%.prototype.subarray transitioning javascript builtin TypedArrayPrototypeSubArray( - context: Context, receiver: Object, ...arguments): JSTypedArray { + js-implicit context: Context, + receiver: Object)(...arguments): JSTypedArray { const methodName: constexpr string = '%TypedArray%.prototype.subarray'; // 1. Let O be the this value. diff --git a/deps/v8/src/builtins/typed-array.tq b/deps/v8/src/builtins/typed-array.tq index 8f923947f1..d03c1a0be9 100644 --- a/deps/v8/src/builtins/typed-array.tq +++ b/deps/v8/src/builtins/typed-array.tq @@ -65,29 +65,18 @@ namespace typed_array { implicit context: Context)(JSTypedArray): JSArrayBuffer; extern macro TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo( JSTypedArray): TypedArrayElementsInfo; + extern macro TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(Map): + TypedArrayElementsInfo; extern macro TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind( ElementsKind): bool; extern macro LoadFixedTypedArrayElementAsTagged( - RawPtr, Smi, constexpr ElementsKind, constexpr ParameterMode): Object; + RawPtr, Smi, constexpr ElementsKind): Numeric; extern macro StoreJSTypedArrayElementFromTagged( - Context, JSTypedArray, Smi, Object, constexpr ElementsKind, - constexpr ParameterMode); + Context, JSTypedArray, Smi, Object, constexpr ElementsKind); type LoadFn = builtin(Context, JSTypedArray, Smi) => Object; type StoreFn = builtin(Context, JSTypedArray, Smi, Object) => Object; - // These UnsafeCast specializations are necessary becuase there is no - // way to definitively test whether an Object is a Torque function - // with a specific signature, and the default UnsafeCast implementation - // would try to check this through an assert(Is<>), so the test - // is bypassed in this specialization. - UnsafeCast<LoadFn>(implicit context: Context)(o: Object): LoadFn { - return %RawDownCast<LoadFn>(o); - } - UnsafeCast<StoreFn>(implicit context: Context)(o: Object): StoreFn { - return %RawDownCast<StoreFn>(o); - } - // AttachedJSTypedArray guards that the array's buffer is not detached. transient type AttachedJSTypedArray extends JSTypedArray; @@ -201,17 +190,16 @@ namespace typed_array { } builtin LoadFixedElement<T: type>( - context: Context, array: JSTypedArray, index: Smi): Object { + _context: Context, array: JSTypedArray, index: Smi): Object { return LoadFixedTypedArrayElementAsTagged( - array.data_ptr, index, KindForArrayType<T>(), SMI_PARAMETERS); + array.data_ptr, index, KindForArrayType<T>()); } builtin StoreFixedElement<T: type>( context: Context, typedArray: JSTypedArray, index: Smi, value: Object): Object { StoreJSTypedArrayElementFromTagged( - context, typedArray, index, value, KindForArrayType<T>(), - SMI_PARAMETERS); + context, typedArray, index, value, KindForArrayType<T>()); return Undefined; } @@ -288,7 +276,8 @@ namespace typed_array { // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.sort transitioning javascript builtin TypedArrayPrototypeSort( - context: Context, receiver: Object, ...arguments): JSTypedArray { + js-implicit context: Context, + receiver: Object)(...arguments): JSTypedArray { // 1. If comparefn is not undefined and IsCallable(comparefn) is false, // throw a TypeError exception. const comparefnObj: Object = @@ -322,7 +311,7 @@ namespace typed_array { let loadfn: LoadFn; let storefn: StoreFn; - let elementsKind: ElementsKind = array.elements_kind; + const elementsKind: ElementsKind = array.elements_kind; if (IsElementsKindGreaterThan(elementsKind, UINT32_ELEMENTS)) { if (elementsKind == INT32_ELEMENTS) { diff --git a/deps/v8/src/builtins/x64/builtins-x64.cc b/deps/v8/src/builtins/x64/builtins-x64.cc index 5c09b3a8de..f15c8ba29f 100644 --- a/deps/v8/src/builtins/x64/builtins-x64.cc +++ b/deps/v8/src/builtins/x64/builtins-x64.cc @@ -1109,10 +1109,10 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // 8-bit fields next to each other, so we could just optimize by writing a // 16-bit. These static asserts guard our assumption is valid. STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == - BytecodeArray::kOSRNestingLevelOffset + kCharSize); + BytecodeArray::kOsrNestingLevelOffset + kCharSize); STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0); __ movw(FieldOperand(kInterpreterBytecodeArrayRegister, - BytecodeArray::kOSRNestingLevelOffset), + BytecodeArray::kOsrNestingLevelOffset), Immediate(0)); // Load initial bytecode offset. @@ -1562,7 +1562,15 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, kSystemPointerSize; __ popq(Operand(rsp, offsetToPC)); __ Drop(offsetToPC / kSystemPointerSize); - __ addq(Operand(rsp, 0), Immediate(Code::kHeaderSize - kHeapObjectTag)); + + // Replace the builtin index Smi on the stack with the instruction start + // address of the builtin from the builtins table, and then Ret to this + // address + __ movq(kScratchRegister, Operand(rsp, 0)); + __ movq(kScratchRegister, + __ EntryFromBuiltinIndexAsOperand(kScratchRegister)); + __ movq(Operand(rsp, 0), kScratchRegister); + __ Ret(); } } // namespace @@ -3002,21 +3010,24 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, __ movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); __ addl(Operand(base_reg, kLevelOffset), Immediate(1)); - Label profiler_disabled; - Label end_profiler_check; + Label profiler_enabled, end_profiler_check; __ Move(rax, ExternalReference::is_profiling_address(isolate)); __ cmpb(Operand(rax, 0), Immediate(0)); - __ j(zero, &profiler_disabled); - - // Third parameter is the address of the actual getter function. - __ Move(thunk_last_arg, function_address); - __ Move(rax, thunk_ref); - __ jmp(&end_profiler_check); - - __ bind(&profiler_disabled); - // Call the api function! - __ Move(rax, function_address); - + __ j(not_zero, &profiler_enabled); + __ Move(rax, ExternalReference::address_of_runtime_stats_flag()); + __ cmpl(Operand(rax, 0), Immediate(0)); + __ j(not_zero, &profiler_enabled); + { + // Call the api function directly. + __ Move(rax, function_address); + __ jmp(&end_profiler_check); + } + __ bind(&profiler_enabled); + { + // Third parameter is the address of the actual getter function. + __ Move(thunk_last_arg, function_address); + __ Move(rax, thunk_ref); + } __ bind(&end_profiler_check); // Call the api function! @@ -3065,6 +3076,9 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, __ CompareRoot(map, RootIndex::kHeapNumberMap); __ j(equal, &ok, Label::kNear); + __ CompareRoot(map, RootIndex::kBigIntMap); + __ j(equal, &ok, Label::kNear); + __ CompareRoot(return_value, RootIndex::kUndefinedValue); __ j(equal, &ok, Label::kNear); |