Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Clean up the JSObjectRef API #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Aug 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ node_modules
/Packages
/*.xcodeproj
xcuserdata/
.swiftpm
5 changes: 2 additions & 3 deletions IntegrationTests/TestSuites/Sources/BenchmarkTests/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ serialization.testSuite("Swift Int to JavaScript") {
let jsNumber = JSValue.number(swiftInt)
let object = JSObjectRef.global
for i in 0 ..< 100 {
object.set("numberValue\(i)", jsNumber)
object["numberValue\(i)"] = jsNumber
}
}

Expand All @@ -16,11 +16,10 @@ serialization.testSuite("Swift String to JavaScript") {
let jsString = JSValue.string(swiftString)
let object = JSObjectRef.global
for i in 0 ..< 100 {
object.set("stringValue\(i)", jsString)
object["stringValue\(i)"] = jsString
}
}


let objectHeap = Benchmark("Object heap")

let global = JSObjectRef.global
Expand Down
22 changes: 11 additions & 11 deletions IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ New_Object_Construction: do {
let cat1 = objectConstructor.new("Tama", 3, true)
try expectEqual(getJSValue(this: cat1, name: "name"), .string("Tama"))
try expectEqual(getJSValue(this: cat1, name: "age"), .number(3))
try expectEqual(cat1.instanceof(objectConstructor), true)
try expectEqual(cat1.instanceof(try expectFunction(getJSValue(this: .global, name: "Array"))), false)
try expectEqual(cat1.isInstanceOf(objectConstructor), true)
try expectEqual(cat1.isInstanceOf(try expectFunction(getJSValue(this: .global, name: "Array"))), false)
let cat1Bark = try expectFunction(getJSValue(this: cat1, name: "bark"))
try expectEqual(cat1Bark(), .string("nyan"))

Expand Down Expand Up @@ -273,20 +273,20 @@ Call_Function_With_This: do {
try expectEqual(getIsCat(), .undefined)

// Call with this
let gotIsCat = getIsCat.apply(this: cat1)
let gotIsCat = getIsCat(this: cat1)
try expectEqual(gotIsCat, .boolean(true))

} catch {
print(error)
}

Object_Conversion: do {
let array1 = [1, 2, 3]
let jsArray1 = array1.jsValue().object!
try expectEqual(jsArray1.length, .number(3))
try expectEqual(jsArray1[0], .number(1))
try expectEqual(jsArray1[1], .number(2))
try expectEqual(jsArray1[2], .number(3))
let array1 = [1, 2, 3]
let jsArray1 = array1.jsValue().object!
try expectEqual(jsArray1.length, .number(3))
try expectEqual(jsArray1[0], .number(1))
try expectEqual(jsArray1[1], .number(2))
try expectEqual(jsArray1[2], .number(3))

let array2: [JSValueConvertible] = [1, "str", false]
let jsArray2 = array2.jsValue().object!
Expand All @@ -296,9 +296,9 @@ Object_Conversion: do {
try expectEqual(jsArray2[2], .boolean(false))
_ = jsArray2.push!(5)
try expectEqual(jsArray2.length, .number(4))
_ = jsArray2.push!(jsArray1)
_ = jsArray2.push!(jsArray1)

try expectEqual(jsArray2[4], .object(jsArray1))
try expectEqual(jsArray2[4], .object(jsArray1))

let dict1: [String: JSValueConvertible] = [
"prop1": 1,
Expand Down
6 changes: 3 additions & 3 deletions Sources/JavaScriptKit/JSArrayRef.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ public class JSArrayRef {
static let classObject = JSObjectRef.global.Array.function!

static func isArray(_ object: JSObjectRef) -> Bool {
classObject.isArray.function!(object).boolean!
classObject.isArray!(object).boolean!
}

let ref: JSObjectRef
Expand Down Expand Up @@ -33,13 +33,13 @@ extension JSArrayRef: RandomAccessCollection {
guard index < Int(ref.length.number!) else {
return nil
}
let value = ref.get(index)
let value = ref[index]
return value.isNull ? nil : value
}
}

public subscript(position: Int) -> JSValue {
ref.get(position)
ref[position]
}

public var startIndex: Int { 0 }
Expand Down
51 changes: 25 additions & 26 deletions Sources/JavaScriptKit/JSFunction.swift
Original file line number Diff line number Diff line change
@@ -1,45 +1,44 @@
import _CJavaScriptKit

@dynamicCallable
public class JSFunctionRef: JSObjectRef {
@discardableResult
public func dynamicallyCall(withArguments arguments: [JSValueConvertible]) -> JSValue {
let result = arguments.withRawJSValues { rawValues -> RawJSValue in
public func callAsFunction(this: JSObjectRef? = nil, arguments: [JSValueConvertible]) -> JSValue {
let result = arguments.withRawJSValues { rawValues in
rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in
let argv = bufferPointer.baseAddress
let argc = bufferPointer.count
var result = RawJSValue()
_call_function(
self.id, argv, Int32(argc),
&result.kind, &result.payload1, &result.payload2, &result.payload3
)
if let thisId = this?.id {
_call_function_with_this(thisId,
self.id, argv, Int32(argc),
&result.kind, &result.payload1, &result.payload2, &result.payload3)
} else {
_call_function(
self.id, argv, Int32(argc),
&result.kind, &result.payload1, &result.payload2, &result.payload3
)
}
return result
}
}
return result.jsValue()
}

public func apply(this: JSObjectRef, arguments: JSValueConvertible...) -> JSValue {
apply(this: this, argumentList: arguments)
@discardableResult
public func callAsFunction(this: JSObjectRef? = nil, _ arguments: JSValueConvertible...) -> JSValue {
self(this: this, arguments: arguments)
}

public func apply(this: JSObjectRef, argumentList: [JSValueConvertible]) -> JSValue {
let result = argumentList.withRawJSValues { rawValues in
rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in
let argv = bufferPointer.baseAddress
let argc = bufferPointer.count
var result = RawJSValue()
_call_function_with_this(this.id,
self.id, argv, Int32(argc),
&result.kind, &result.payload1, &result.payload2, &result.payload3)
return result
}
}
return result.jsValue()
public func new(_ arguments: JSValueConvertible...) -> JSObjectRef {
new(arguments: arguments)
}

public func new(_ arguments: JSValueConvertible...) -> JSObjectRef {
return arguments.withRawJSValues { rawValues in
// Guaranteed to return an object because either:
// a) the constructor explicitly returns an object, or
// b) the constructor returns nothing, which causes JS to return the `this` value, or
// c) the constructor returns undefined, null or a non-object, in which case JS also returns `this`.
public func new(arguments: [JSValueConvertible]) -> JSObjectRef {
arguments.withRawJSValues { rawValues in
rawValues.withUnsafeBufferPointer { bufferPointer in
let argv = bufferPointer.baseAddress
let argc = bufferPointer.count
Expand Down Expand Up @@ -106,10 +105,10 @@ public func _call_host_function(
guard let hostFunc = JSClosure.sharedFunctions[hostFuncRef] else {
fatalError("The function was already released")
}
let args = UnsafeBufferPointer(start: argv, count: Int(argc)).map {
let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map {
$0.jsValue()
}
let result = hostFunc(args)
let result = hostFunc(arguments)
let callbackFuncRef = JSFunctionRef(id: callbackFuncRef)
_ = callbackFuncRef(result)
}
33 changes: 11 additions & 22 deletions Sources/JavaScriptKit/JSObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,29 @@ public class JSObjectRef: Equatable {

@_disfavoredOverload
public subscript(dynamicMember name: String) -> ((JSValueConvertible...) -> JSValue)? {
guard let function = self[dynamicMember: name].function else { return nil }
guard let function = self[name].function else { return nil }
return { (arguments: JSValueConvertible...) in
function.apply(this: self, argumentList: arguments)
function(this: self, arguments: arguments)
}
}

public subscript(dynamicMember name: String) -> JSValue {
get { get(name) }
set { set(name, newValue) }
get { self[name] }
set { self[name] = newValue }
}

public func get(_ name: String) -> JSValue {
getJSValue(this: self, name: name)
}

public func set(_ name: String, _ value: JSValue) {
setJSValue(this: self, name: name, value: value)
}

public func get(_ index: Int) -> JSValue {
getJSValue(this: self, index: Int32(index))
}

public func instanceof(_ constructor: JSFunctionRef) -> Bool {
_instanceof(self.id, constructor.id)
public subscript(_ name: String) -> JSValue {
get { getJSValue(this: self, name: name) }
set { setJSValue(this: self, name: name, value: newValue) }
}

public subscript(_ index: Int) -> JSValue {
get { get(index) }
set { set(index, newValue) }
get { getJSValue(this: self, index: Int32(index)) }
set { setJSValue(this: self, index: Int32(index), value: newValue) }
}

public func set(_ index: Int, _ value: JSValue) {
setJSValue(this: self, index: Int32(index), value: value)
public func isInstanceOf(_ constructor: JSFunctionRef) -> Bool {
_instanceof(id, constructor.id)
}

static let _JS_Predef_Value_Global: UInt32 = 0
Expand Down
2 changes: 1 addition & 1 deletion Sources/JavaScriptKit/JSValueConvertible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ extension Dictionary: JSValueConvertible where Value == JSValueConvertible, Key
public func jsValue() -> JSValue {
let object = Object.new()
for (key, value) in self {
object.set(key, value.jsValue())
object[key] = value.jsValue()
}
return .object(object)
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/JavaScriptKit/JSValueDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private struct _Decoder: Decoder {
}

private enum Object {
static let ref = JSObjectRef.global.get("Object").object!
static let ref = JSObjectRef.global.Object.object!
static func keys(_ object: JSObjectRef) -> [String] {
let keys = ref.keys!(object).array!
return keys.map { $0.string! }
Expand Down Expand Up @@ -90,7 +90,7 @@ private struct _KeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContainerPr
}

func _decode(forKey key: CodingKey) throws -> JSValue {
let result = ref.get(key.stringValue)
let result = ref[key.stringValue]
guard !result.isUndefined else {
throw _keyNotFound(at: codingPath, key)
}
Expand All @@ -106,7 +106,7 @@ private struct _KeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContainerPr
}

func contains(_ key: Key) -> Bool {
!ref.get(key.stringValue).isUndefined
!ref[key.stringValue].isUndefined
}

func decodeNil(forKey key: Key) throws -> Bool {
Expand Down Expand Up @@ -162,7 +162,7 @@ private struct _UnkeyedDecodingContainer: UnkeyedDecodingContainer {

mutating func _currentValue() -> JSValue {
defer { currentIndex += 1 }
return ref.get(currentIndex)
return ref[currentIndex]
}

mutating func _throwTypeMismatchIfNil<T>(_ transform: (JSValue) -> T?) throws -> T {
Expand Down
2 changes: 1 addition & 1 deletion Sources/JavaScriptKit/XcodeSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import _CJavaScriptKit
) { fatalError() }
func _instanceof(
_: JavaScriptObjectRef,
_: JavaScriptObjectRef
_: JavaScriptObjectRef
) -> Bool { fatalError() }
func _create_function(
_: JavaScriptHostFuncRef,
Expand Down