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 |