compiler, internal/abi: implement FuncPCABI0, FuncPCABIInternal
The Go 1.18 standard library uses an internal/abi package with two functions that are implemented in the compiler. This patch implements them in the gofrontend, to support the upcoming update to 1.18. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/383514
This commit is contained in:
parent
e52a683170
commit
3ab49b1c82
@ -1,4 +1,4 @@
|
||||
61f7cf4b9db0587ff099aa36832a355b90ee1bf9
|
||||
262cb89fd5ed82ab135a3933b2ddf4eb67683149
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
@ -12177,6 +12177,50 @@ Call_expression::intrinsify(Gogo* gogo,
|
||||
return Runtime::make_call(code, loc, 3, a1, a2, a3);
|
||||
}
|
||||
}
|
||||
else if (package == "internal/abi")
|
||||
{
|
||||
if ((name == "FuncPCABI0" || name == "FuncPCABIInternal")
|
||||
&& this->args_ != NULL
|
||||
&& this->args_->size() == 1)
|
||||
{
|
||||
// We expect to see a conversion from the expression to "any".
|
||||
Expression* expr = this->args_->front();
|
||||
Type_conversion_expression* tce = expr->conversion_expression();
|
||||
if (tce != NULL)
|
||||
expr = tce->expr();
|
||||
Func_expression* fe = expr->func_expression();
|
||||
Interface_field_reference_expression* interface_method =
|
||||
expr->interface_field_reference_expression();
|
||||
if (fe != NULL)
|
||||
{
|
||||
Named_object* no = fe->named_object();
|
||||
Expression* ref = Expression::make_func_code_reference(no, loc);
|
||||
Type* uintptr_type = Type::lookup_integer_type("uintptr");
|
||||
return Expression::make_cast(uintptr_type, ref, loc);
|
||||
}
|
||||
else if (interface_method != NULL)
|
||||
return interface_method->get_function();
|
||||
else
|
||||
{
|
||||
expr = this->args_->front();
|
||||
go_assert(expr->type()->interface_type() != NULL
|
||||
&& expr->type()->interface_type()->is_empty());
|
||||
expr = Expression::make_interface_info(expr,
|
||||
INTERFACE_INFO_OBJECT,
|
||||
loc);
|
||||
// Trust that this is a function type, which means that
|
||||
// it is a direct iface type and we can use EXPR
|
||||
// directly. The backend representation of this
|
||||
// function is a pointer to a struct whose first field
|
||||
// is the actual function to call.
|
||||
Type* pvoid = Type::make_pointer_type(Type::make_void_type());
|
||||
Type* pfntype = Type::make_pointer_type(pvoid);
|
||||
Expression* ref = make_unsafe_cast(pfntype, expr, loc);
|
||||
return Expression::make_dereference(ref, NIL_CHECK_NOT_NEEDED,
|
||||
loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
35
libgo/go/internal/abi/abi.go
Normal file
35
libgo/go/internal/abi/abi.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package abi
|
||||
|
||||
// FuncPC* intrinsics.
|
||||
//
|
||||
// CAREFUL: In programs with plugins, FuncPC* can return different values
|
||||
// for the same function (because there are actually multiple copies of
|
||||
// the same function in the address space). To be safe, don't use the
|
||||
// results of this function in any == expression. It is only safe to
|
||||
// use the result as an address at which to start executing code.
|
||||
|
||||
// FuncPCABI0 returns the entry PC of the function f, which must be a
|
||||
// direct reference of a function defined as ABI0. Otherwise it is a
|
||||
// compile-time error.
|
||||
//
|
||||
// Implemented as a compile intrinsic.
|
||||
func FuncPCABI0(f any) uintptr {
|
||||
// The compiler should remove all calls.
|
||||
panic("FuncPCABI0")
|
||||
}
|
||||
|
||||
// FuncPCABIInternal returns the entry PC of the function f. If f is a
|
||||
// direct reference of a function, it must be defined as ABIInternal.
|
||||
// Otherwise it is a compile-time error. If f is not a direct reference
|
||||
// of a defined function, it assumes that f is a func value. Otherwise
|
||||
// the behavior is undefined.
|
||||
//
|
||||
// Implemented as a compile intrinsic.
|
||||
func FuncPCABIInternal(f any) uintptr {
|
||||
// The compiler should remove all calls.
|
||||
panic("FuncPCABIInternal")
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"internal/abi"
|
||||
"internal/cpu"
|
||||
"runtime/internal/atomic"
|
||||
"runtime/internal/sys"
|
||||
@ -4243,11 +4244,11 @@ func _GC() { _GC() }
|
||||
func _LostSIGPROFDuringAtomic64() { _LostSIGPROFDuringAtomic64() }
|
||||
func _VDSO() { _VDSO() }
|
||||
|
||||
var _SystemPC = funcPC(_System)
|
||||
var _ExternalCodePC = funcPC(_ExternalCode)
|
||||
var _LostExternalCodePC = funcPC(_LostExternalCode)
|
||||
var _GCPC = funcPC(_GC)
|
||||
var _LostSIGPROFDuringAtomic64PC = funcPC(_LostSIGPROFDuringAtomic64)
|
||||
var _SystemPC = abi.FuncPCABIInternal(_System)
|
||||
var _ExternalCodePC = abi.FuncPCABIInternal(_ExternalCode)
|
||||
var _LostExternalCodePC = abi.FuncPCABIInternal(_LostExternalCode)
|
||||
var _GCPC = abi.FuncPCABIInternal(_GC)
|
||||
var _LostSIGPROFDuringAtomic64PC = abi.FuncPCABIInternal(_LostSIGPROFDuringAtomic64)
|
||||
|
||||
// Called if we receive a SIGPROF signal.
|
||||
// Called by the signal handler, may run during STW.
|
||||
|
@ -113,6 +113,7 @@ image/internal/imageutil
|
||||
image/jpeg
|
||||
image/png
|
||||
index/suffixarray
|
||||
internal/abi
|
||||
internal/buildcfg
|
||||
internal/bytealg
|
||||
internal/cfg
|
||||
|
Loading…
Reference in New Issue
Block a user