OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/ffi/ffi-compiler.h" |
| 6 #include "src/api.h" |
| 7 #include "src/code-factory.h" |
| 8 |
| 9 namespace v8 { |
| 10 namespace internal { |
| 11 |
| 12 void InstallFFIMap(Isolate* isolate) { |
| 13 Handle<Context> context(isolate->context()); |
| 14 DCHECK(!context->get(Context::NATIVE_FUNCTION_MAP_INDEX)->IsMap()); |
| 15 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
| 16 |
| 17 InstanceType instance_type = prev_map->instance_type(); |
| 18 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
| 19 CHECK_EQ(0, internal_fields); |
| 20 int pre_allocated = |
| 21 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); |
| 22 int instance_size; |
| 23 int in_object_properties; |
| 24 JSFunction::CalculateInstanceSizeHelper( |
| 25 instance_type, internal_fields, 0, &instance_size, &in_object_properties); |
| 26 int unused_property_fields = in_object_properties - pre_allocated; |
| 27 Handle<Map> map = Map::CopyInitialMap( |
| 28 prev_map, instance_size, in_object_properties, unused_property_fields); |
| 29 context->set_native_function_map(*map); |
| 30 } |
| 31 |
| 32 namespace ffi { |
| 33 |
| 34 class FFIAssembler : public CodeStubAssembler { |
| 35 public: |
| 36 explicit FFIAssembler(CodeAssemblerState* state) : CodeStubAssembler(state) {} |
| 37 |
| 38 Node* ToJS(Node* node, Node* context, MachineType type) { |
| 39 UNREACHABLE(); |
| 40 // TODO(mattloring): Needs to be implemented. |
| 41 return nullptr; |
| 42 } |
| 43 |
| 44 Node* FromJS(Node* node, Node* context, MachineType type) { |
| 45 UNREACHABLE(); |
| 46 // TODO(mattloring): Needs to be implemented. |
| 47 return nullptr; |
| 48 } |
| 49 |
| 50 void GenerateJSToNativeWrapper(NativeFunction* func) { |
| 51 int params = static_cast<int>(func->sig->parameter_count()); |
| 52 int returns = static_cast<int>(func->sig->return_count()); |
| 53 ApiFunction api_func(func->start); |
| 54 ExternalReference ref(&api_func, ExternalReference::DIRECT_API_CALL, |
| 55 isolate()); |
| 56 |
| 57 Node* context_param = GetJSContextParameter(); |
| 58 |
| 59 Node** inputs = zone()->NewArray<Node*>(params + 1); |
| 60 int input_count = 0; |
| 61 inputs[input_count++] = ExternalConstant(ref); |
| 62 for (int i = 0; i < params; i++) { |
| 63 inputs[input_count++] = |
| 64 FromJS(Parameter(i), context_param, func->sig->GetParam(i)); |
| 65 } |
| 66 |
| 67 Node* call = CallCFunctionN(func->sig, input_count, inputs); |
| 68 Node* return_val = UndefinedConstant(); |
| 69 if (returns == 1) { |
| 70 return_val = ToJS(call, context_param, func->sig->GetReturn()); |
| 71 } |
| 72 Return(return_val); |
| 73 } |
| 74 }; |
| 75 |
| 76 Handle<JSFunction> CompileJSToNativeWrapper(Isolate* isolate, |
| 77 Handle<String> name, |
| 78 NativeFunction func) { |
| 79 int params = static_cast<int>(func.sig->parameter_count()); |
| 80 Zone zone(isolate->allocator(), ZONE_NAME); |
| 81 CodeAssemblerState state(isolate, &zone, params, |
| 82 Code::ComputeFlags(Code::FUNCTION), "js-to-native"); |
| 83 FFIAssembler assembler(&state); |
| 84 assembler.GenerateJSToNativeWrapper(&func); |
| 85 Handle<Code> code = assembler.GenerateCode(&state); |
| 86 |
| 87 Handle<SharedFunctionInfo> shared = |
| 88 isolate->factory()->NewSharedFunctionInfo(name, code, false); |
| 89 shared->set_length(params); |
| 90 shared->set_internal_formal_parameter_count(params); |
| 91 Handle<JSFunction> function = isolate->factory()->NewFunction( |
| 92 isolate->native_function_map(), name, code); |
| 93 function->set_shared(*shared); |
| 94 return function; |
| 95 } |
| 96 |
| 97 } // namespace ffi |
| 98 } // namespace internal |
| 99 } // namespace v8 |
OLD | NEW |