Chromium Code Reviews| Index: src/ffi/ffi-compiler.cc |
| diff --git a/src/ffi/ffi-compiler.cc b/src/ffi/ffi-compiler.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..23a3bee149cfd6b9597d8701df412e7b31ef971f |
| --- /dev/null |
| +++ b/src/ffi/ffi-compiler.cc |
| @@ -0,0 +1,102 @@ |
| +// Copyright 2016 the V8 project authors. All rights reserved. |
|
Michael Starzinger
2017/01/18 10:47:23
nit: 2017
mattloring
2017/01/18 17:48:18
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "src/ffi/ffi-compiler.h" |
| + |
| +#include "src/api.h" |
| +#include "src/code-factory.h" |
| +#include "src/code-stub-assembler.h" |
| +#include "src/compilation-info.h" |
| +#include "src/isolate-inl.h" |
| + |
| +namespace v8 { |
| +namespace internal { |
| + |
| +using compiler::CodeAssembler; |
| +using compiler::CodeAssemblerState; |
| +using compiler::Node; |
| + |
| +void InstallFFIMap(Isolate* isolate) { |
| + Handle<Context> context(isolate->context()); |
| + DCHECK(!context->get(Context::NATIVE_FUNCTION_MAP_INDEX)->IsMap()); |
| + Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
| + |
| + InstanceType instance_type = prev_map->instance_type(); |
| + int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
| + CHECK_EQ(0, internal_fields); |
| + int pre_allocated = |
| + prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); |
| + int instance_size; |
| + int in_object_properties; |
| + JSFunction::CalculateInstanceSizeHelper( |
| + instance_type, internal_fields, 0, &instance_size, &in_object_properties); |
| + int unused_property_fields = in_object_properties - pre_allocated; |
| + Handle<Map> map = Map::CopyInitialMap( |
| + prev_map, instance_size, in_object_properties, unused_property_fields); |
| + context->set_native_function_map(*map); |
| +} |
| + |
| +namespace ffi { |
| + |
| +Node* ToJS(CodeStubAssembler* assembler, Node* node, Node* context, |
|
Igor Sheludko
2017/01/18 15:20:22
I'd suggest to define a FFIAssembler (or similar)
mattloring
2017/01/18 17:48:18
Done.
|
| + MachineType type) { |
| + UNREACHABLE(); |
| + // TODO(mattloring): Needs to be implemented. |
| + return nullptr; |
| +} |
| + |
| +Node* FromJS(CodeStubAssembler* assembler, Node* node, Node* context, |
| + MachineType type) { |
| + UNREACHABLE(); |
| + // TODO(mattloring): Needs to be implemented. |
| + return nullptr; |
| +} |
| + |
| +Handle<JSFunction> CompileJSToNativeWrapper(Isolate* isolate, |
| + Handle<String> name, |
| + ffi::NativeFunction func) { |
| + int params = static_cast<int>(func.sig->parameter_count()); |
| + int returns = static_cast<int>(func.sig->return_count()); |
| + Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( |
| + name, MaybeHandle<Code>(), false); |
| + shared->set_length(params); |
| + shared->set_internal_formal_parameter_count(params); |
| + Handle<JSFunction> function = isolate->factory()->NewFunction( |
| + isolate->native_function_map(), name, MaybeHandle<Code>()); |
| + function->set_shared(*shared); |
| + |
| + Zone zone(isolate->allocator(), ZONE_NAME); |
| + int params_with_recv = params + 1; |
| + CodeAssemblerState state(isolate, &zone, params_with_recv, |
| + Code::ComputeFlags(Code::FUNCTION), "js-to-native"); |
| + CodeStubAssembler assembler(&state); |
|
Igor Sheludko
2017/01/18 15:20:22
... create it here, call
assembler.GenerateJSToN
mattloring
2017/01/18 17:48:18
Done.
|
| + |
| + ApiFunction api_func(func.start); |
| + ExternalReference ref(&api_func, ExternalReference::DIRECT_API_CALL, isolate); |
| + |
| + Node* context_param = assembler.GetJSContextParameter(); |
| + |
| + Node** inputs = zone.NewArray<Node*>(params + 1); |
| + int input_count = 0; |
| + inputs[input_count++] = assembler.ExternalConstant(ref); |
| + for (int i = 0; i < params; i++) { |
| + inputs[input_count++] = FromJS(&assembler, assembler.Parameter(i), |
| + context_param, func.sig->GetParam(i)); |
| + } |
| + |
| + Node* call = assembler.CallCFunctionN(func.sig, input_count, inputs); |
| + Node* return_val = assembler.UndefinedConstant(); |
| + if (returns == 1) { |
| + return_val = ToJS(&assembler, call, context_param, func.sig->GetReturn()); |
| + } |
| + assembler.Return(return_val); |
| + |
| + Handle<Code> code = CodeAssembler::GenerateCode(&state); |
| + function->set_code(*code); |
| + return function; |
| +} |
| + |
| +} // namespace ffi |
| +} // namespace internal |
| +} // namespace v8 |